Vue 组件(component)教程之实现精美的日历方法示

组件(component)是Vue最强大的功能之一。组件可以扩展HTML元素,封装可重用的代码,根据项目需求,抽象出一些组件,每个组件里包含了展现、功能和样式。每个页面,根据自己的需要,使用不同的组件来拼接页面。这种开发模式使得前端页面易于扩展,且灵活性高,而且组件之间也实现了解耦。

最近应公司的要求,需要开发一个精美的日历组件(IOS , 安卓, PC 的IE9+都能运行),写完后想把它分享出来,希望大家批评。

先来个截图

Vue 组件(component)教程之实现精美的日历方法示

  

代码已经分享到 https://github.com/zhangKunUserGit/vue-component  (本地下载

使用方法

根据需求先说一下怎么用吧 (上面是:HTML, 下面是JS )

<date-picker v-if="showDatePicker" :date="date" :min-date="minDate" :max-date="maxDate" @confirm="confirm" @cancel="cancel" ></date-picker>

import DataPicker from './components/DatePicker.vue'; import './style.scss'; new Vue({ el: '#app', data() { return { date: '2017-09-11', minDate: '2000-09-11', maxDate: '2020-09-11', showDatePicker: false, selectedDate: '点击选择日期', }; }, methods: { openDatePicker() { this.showDatePicker = true; }, confirm(value) { this.showDatePicker = false; this.selectedDate = value; }, cancel() { this.showDatePicker = false; }, }, components: { DataPicker, }, });

我们提供了最大值、最小值和初始值,唯一不足的地方是时间格式只能是YYYY-MM-DD (2017-12-12) ,大家可以从github上拉取代码运行看一下(由于没有仔细测试,可能会有bug和性能问题,希望指出)。

(一)先画好界面

这个不是重点,HTML 和 CSS,应该很简单,大家看我的css 可能感觉我的命名太长了,只因为我们公司用,担心其他样式影响它(可能有其他方式吧,希望大神指出)

(二)组装日期列表

先看代码:

rows() { const { year, month } = this.showDate; const months = (new Date(year, month, 0)).getDate(); const result = []; let row = []; let weekValue; // 按照星期分组 for (let i = 1; i <= months; i += 1) { // 根据日期获取星期,并让开头是1,而非0 weekValue = (new Date(year, month, i)).getDay() + 1; // 判断月第一天在星期几,并填充前面的空白区域 if (i === 1 && weekValue !== 1) { this.addRowEmptyValue(row, weekValue); this.addRowDayValue(row, i); } else { this.addRowDayValue(row, i); // 判断月最后一天在星期几,并填充后面的空白区域 if (i === months && weekValue !== 7) { this.addRowEmptyValue(row, (7 - weekValue) + 1); } } // 按照一周分组 if (weekValue % 7 === 0 || i === months) { result.push(row); row = []; } } this.showDate.monthStr = monthJson[this.showDate.month]; return result; },

我的思路是:

(1)获取月份天数,并按照星期分组;

(2)如果月份第一天不在星期一,前面填充空值。同理,如何月份最后一天不在周日,最后面填充空值,目的是:让分的组 长度都是7,也就是一周。这样可以用flex布局方式快速开发了;

(3)里面也包含一些限制,比如小于minDate和大于maxDate, 不让点击等等

(三)切换月份 (1)上一个月份

/** * 切换到上一个月 */ prevMonth() { if (this.prevMonthClick) { return; } this.prevMonthClick = true; setTimeout(() => { this.prevMonthClick = false; }, 500); this.fadeXType = 'fadeX_Prev'; // 如何当前月份已经小于等于minMonth 就不让其在执行 if (this.isMinLimitMonth()) { return; } const { year, month } = this.showDate; // 判断当前月份,如果已经等于1(1就是一月,而不是二月) if (month <= 1) { this.showDate.year = year - 1; this.showDate.month = 12; } else { this.showDate.month -= 1; } },

setTimeout()主要是让其显示动画后自动消失。 fadeXType 是动画类型

(2)下一个月份

/** * 切换到下一个月 */ nextMonth() { if (this.nextMonthClick) { return; } this.nextMonthClick = true; setTimeout(() => { this.nextMonthClick = false; }, 500); this.fadeXType = 'fadeX_Next'; // 如何当前月份已经大于等于maxMonth 就不让其在执行 if (this.isMaxLimitMonth()) { return; } const { year, month } = this.showDate; // 判断当前月份,如果已经等于12(12就是十二月) if (month >= 12) { this.showDate.year = year + 1; this.showDate.month = 1; } else { this.showDate.month += 1; } },

这里面的setTimeout() 和prevMonth方法的原理一样。

上面两种切换月份的功能主要注意:

a. 因为有minDate和maxDate,所以首先考虑的是不能超出这个限制。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/wyywxd.html