上一篇我们已经实现了基本的日历显示功能,这一次我们要加上预定的功能

废话不多说,上代码

<div id="calendar">
<!-- 年份 月份 -->
<div class="month">
<ul>
<!--点击会触发pickpre函数,重新刷新当前日期 @click(vue v-on:click缩写) -->
<li class="arrow" @click="pickPre(currentYear,currentMonth)">❮</li>
<li class="year-month" @click="pickYear(currentYear,currentMonth)">
<span class="choose-year">{{ currentYear }}</span>
<span class="choose-month">{{ currentMonth }}月</span>
</li>
<li class="arrow" @click="pickNext(currentYear,currentMonth)">❯</li>
</ul>
</div>
<!-- 星期 -->
<ul class="weekdays">
<li>一</li>
<li>二</li>
<li>三</li>
<li>四</li>
<li>五</li>
<li style="color:red">六</li>
<li style="color:red">日</li>
</ul>
<!-- 日期 -->
<ul class="days">
<!-- v-for循环 每一次循环用<li>标签创建一天 -->
<li v-for="dayobject in days" style="height: 120px;">
<!--本月-->
<!--如果不是本月 改变类名加灰色--> <span v-if="dayobject.day.getMonth()+1 != currentMonth" class="other-month">{{ dayobject.day.getDate() }}</span> <!--如果是本月 还需要判断是不是这一天-->
<span v-else>
<!--今天 同年同月同日-->
<span v-if="dayobject.day.getFullYear() == new Date().getFullYear() && dayobject.day.getMonth() == new Date().getMonth() && dayobject.day.getDate() == new Date().getDate()" class="active">{{ dayobject.day.getDate() }}</span>
<span v-else>{{ dayobject.day.getDate() }}</span>
</span>
<!--显示剩余多少数量-->
<p v-if="leftobj[dayobject.index]">剩余:<span style="color: red" >{{leftobj[dayobject.index].count}}</span></p>
<!---->
<button @click="order(dayobject)" v-if="leftobj[dayobject.index]">预定</button>
</li>
</ul>
</div>

js代码

<script>
var myVue=new Vue({
el: '#calendar',
data: {
currentDay: 1,
currentMonth: 1,
currentYear: 1970,
currentWeek: 1,
days: [],
leftobj:[ //存放剩余数量
{count:1},
{count:2},
{count:3},
{count:4},
{count:5},
], },
created: function() { //在vue初始化时调用
this.initData(null);
},
methods: {
order:function (day) { //预定函数
if(this.leftobj[day.index].count>=1)
this.leftobj[day.index].count--;
else
alert('已经没有位置了')
},
initData: function(cur) {
var leftcount=0; //存放剩余数量
var date;
var index=0; //控制显示预定的天数 ,比如下面设置只能预定三天的
//this.initleftcount(); 每次初始化更新数量
//有两种方案 一种是每次翻页 ajax获取数据初始化 http请求过多会导致资源浪费
// 一种是每次请求 ajax获取数据初始化 数据更新过慢会导致缺少实时性
//还可以setTimeout 定时请求更新数据 实现数据刷新(可能会更好) if (cur) {
date = new Date(cur);
} else {
var now=new Date();
var d = new Date(this.formatDate(now.getFullYear() , now.getMonth() , 1));
d.setDate(35);
date = new Date(this.formatDate(d.getFullYear(),d.getMonth() + 1,1));
}
this.currentDay = date.getDate();
this.currentYear = date.getFullYear();
this.currentMonth = date.getMonth() + 1; this.currentWeek = date.getDay(); // 1...6,0
if (this.currentWeek == 0) {
this.currentWeek = 7;
}
var str = this.formatDate(this.currentYear , this.currentMonth, this.currentDay);
this.days.length = 0;
// 今天是周日,放在第一行第7个位置,前面6个
//初始化本周
for (var i = this.currentWeek - 1; i >= 0; i--) {
var d = new Date(str);
d.setDate(d.getDate() - i); var dayobject={};
dayobject.day=d;
var now=new Date();
if(d.getDate()===(now.getDate())&&d.getMonth()===now.getMonth()&&d.getFullYear()===now.getFullYear())
{
dayobject.index=index++;//从今天开始显示供预定的数量
}
else if(index!=0&&index<3)
dayobject.index=index++;//从今天开始3天内显示供预定的数量 this.days.push(dayobject);//将日期放入data 中的days数组 供页面渲染使用 }
//其他周
for (var i = 1; i <= 35 - this.currentWeek; i++) {
var d = new Date(str);
d.setDate(d.getDate() + i);
var dayobject={};
dayobject.day=d;
var now=new Date();
if(d.getDate()===(now.getDate())&&d.getMonth()===now.getMonth()&&d.getFullYear()===now.getFullYear())
{
dayobject.index=index++;
} else if(index!=0&&index<3)
dayobject.index=index++;
this.days.push(dayobject);
} },
pickPre: function(year, month) { // setDate(0); 上月最后一天
// setDate(-1); 上月倒数第二天
// setDate(dx) 参数dx为 上月最后一天的前后dx天
var d = new Date(this.formatDate(year , month , 1));
d.setDate(0);
this.initData(this.formatDate(d.getFullYear(),d.getMonth() + 1,1));
},
pickNext: function(year, month) {
var d = new Date(this.formatDate(year , month , 1));
d.setDate(35);
this.initData(this.formatDate(d.getFullYear(),d.getMonth() + 1,1));
},
pickYear: function(year, month) {
alert(year + "," + month);
}, // 返回 类似 2016-01-02 格式的字符串
formatDate: function(year,month,day){
var y = year;
var m = month;
if(m<10) m = "0" + m;
var d = day;
if(d<10) d = "0" + d;
return y+"-"+m+"-"+d
}, },
}); </script>

原理就是使用v-if判断当前日期是否具有index属性,如果有,就说明当前天是可供预定的。

在vue data中加入leftobj对象数组,存放每一天剩余数量count的值。

这里有个问题,为什么不直接用一个数组存放每一天的值呢。例如:leftcount:[1,2,3];这样多简便

原因就牵扯到vue 的响应式原理:

看vue的官方介绍

如何追踪变化

把一个普通 JavaScript 对象传给 Vue 实例的 data 选项,Vue 将遍历此对象所有的属性,并使用 Object.defineProperty 把这些属性全部转为 getter/setter。Object.defineProperty 是仅 ES5 支持,且无法 shim 的特性,这也就是为什么 Vue 不支持 IE8 以及更低版本浏览器的原因。
用户看不到 getter/setter,但是在内部它们让 Vue 追踪依赖,在属性被访问和修改时通知变化。这里需要注意的问题是浏览器控制台在打印数据对象时 getter/setter 的格式化并不同,所以你可能需要安装 vue-devtools 来获取更加友好的检查接口。
每个组件实例都有相应的 watcher 实例对象,它会在组件渲染的过程中把属性记录为依赖,之后当依赖项的 setter 被调用时,会通知 watcher 重新计算,从而致使它关联的组件得以更新。

意思就是vue会给data中的每一个对象加上getter/setter属性,由于上面举例leftcount数组中的值都为基本数据类型,无法添加getter/setter属性,所以vue无法渲染它们。

所以我们应该使用对象数组的方式,vue就可以给数组中的每一个对象添加getter/setter属性。

这是一个需要注意的地方。

关于用户预定的这一部分就是这样,下一篇再说管理员设置的部分。

github此项目地址:https://github.com/herozhou/vue-order-calendar

vue初学实践之路——vue简单日历组件(2)的更多相关文章

  1. vue初学实践之路——vue简单日历组件(1)

    ---恢复内容开始--- 最近做的项目有一个需求,需要有一个日历组件供预定功能使用,之前的代码过于繁琐复杂,所以我采用vue重写了这个组件. npm.vue等等安装. 只是一个简单的日历组件,所以并不 ...

  2. vue初学实践之路——vue简单日历组件(3)

    这一篇我们来实现管理员修改每一天剩余数量的功能. <div id="calendar"> <div id="left"> <spa ...

  3. 基于Vue的简单日历组件

    日历组件 由于移动端项目中需要用到日历组件,网上找了下,没看到几个合适的,就尝试着自己写一个.然后发现也不是很复杂,目前只做了最基本的功能,大家也可以拿去做做二次开发. 如何写一个日历组件 基础效果如 ...

  4. Vue 爬坑之路(五)—— 组件进阶

    组件(Component)是 Vue.js 最强大的功能之一,之前的文章都只是用到了基本的封装功能,这次将介绍一些更强大的扩展. 一.基本用法 在使用 vue-cli 创建的项目中,组件的创建非常方便 ...

  5. Vue 爬坑之路(二)—— 组件之间的数据传递

    Vue 的组件作用域都是孤立的,不允许在子组件的模板内直接引用父组件的数据.必须使用特定的方法才能实现组件之间的数据传递. 首先用 vue-cli 创建一个项目,其中 App.vue 是父组件,com ...

  6. (转)Vue 爬坑之路(二)—— 组件之间的数据传递

    Vue 的组件作用域都是孤立的,不允许在子组件的模板内直接引用父组件的数据.必须使用特定的方法才能实现组件之间的数据传递. 首先用 vue-cli 创建一个项目,其中 App.vue 是父组件,com ...

  7. Vue 爬坑之路(九)—— 用正确的姿势封装组件

    迄今为止做的最大的 Vue 项目终于提交测试,天天加班的日子终于告一段落... 在开发过程中,结合 Vue 组件化的特性,开发通用组件是很基础且重要的工作 通用组件必须具备高性能.低耦合的特性 为了满 ...

  8. 一个简单的 vue.js 实践教程

    https://segmentfault.com/a/1190000006776243?utm_source=tuicool&utm_medium=referral 感觉需要改善的地方有: ( ...

  9. 使用ant design vue的日历组件,实现一个简单交易日与非交易日的切换

    使用ant design vue的日历组件,实现一个简单交易日与非交易日的切换 需求: 日历区分交易日.非交易日 可以切换面板查看整年交易日信息 可以在手动调整交易日.非交易日 演示实例 序--使用软 ...

随机推荐

  1. [IDEA_6] IDEA 集成 Python

    0. 说明 在 IDEA 中集成 Python 1. IDEA 集成 Python 1.1 Ctrl + Alt + S 进入设置 依次选中 Settings  -->  Plugins  -- ...

  2. 【转】Linux下从TCP状态机,三次握手判断DDOS攻击

    从TCP状态机判断DDOS攻击 一.TCP协议 TCP 协议是传送层的核心协议,提供了可靠面向连接的协议,分为三次握手和四次断开,在这个过程中TCP有个状态机,记录不同阶段的状态. 二. TCP握手和 ...

  3. SDN2017 第四次作业

    1.阅读 了解SDN控制器的发展 http://www.sdnlab.com/13306.html http://www.docin.com/p-1536626509.html 了解ryu控制器 ht ...

  4. 【Alpha】团队课程展示

    团队展示报告 团队分工 陈涵 PM + 后端开发 ,统筹全队安排,完成了登录界面,以及一部分部门模块和课程中教室模块的编写. 张鹏 后端开发,主要完成了主界面和其他功能界面的编写,课程界面的编写,以及 ...

  5. Alpha课堂展示(麻瓜制造者)

    目录 成员简介 演示动态图 预期用户量 演示动态图 目标用户视频 分工协作 项目管理 质量控制 团队角色与具体贡献 用户反馈 成员简介 刘双玉 http://www.cnblogs.com/liu42 ...

  6. PyQt5--ToolBar

    # -*- coding:utf-8 -*- ''' Created on Sep 14, 2018 @author: SaShuangYiBing ''' import sys from PyQt5 ...

  7. [Python]运算符的优先级顺序

    运算符 描述 ** 指数 (最高优先级) ~ + - 按位翻转, 一元加号和减号 (最后两个的方法名为 +@ 和 -@) * / % // 乘,除,取模和取整除 + - 加法减法 >> & ...

  8. Redis系列三:reids常用命令

    全局命令 keys *  查看所有键 dbsize 查看的是当前所在redis数据库的键总数 如果存在大量键,线上禁止使用此指令 exists key 检查键是否存在,存在返回1,不存在返回0 del ...

  9. android studio InnerClass annotations are missing corresponding EnclosingMember annotations. Such InnerClass annota

    如果 你的项目中使用了注解插件 比如butterknife   升级3.1之后打包编译  出现以下错误提示 InnerClass annotations are missing correspondi ...

  10. 利用单例模式设计数据库连接Model类

    之前在<[php]利用php的构造函数与析构函数编写Mysql数据库查询类>(点击打开链接)写过的Mysql数据库查询类还不够完美,利用<[Java]单例模式>(点击打开链接) ...