前言:授人以鱼不如授人以渔,与其寻寻觅觅找一个适合自己UI的选择器控件,不如自己动手,尝试一下。
如果你还不会 Vue.js 那么请移步 Vue.js 官网;如果你已经掌握了如何使用,那么就请跟着我一起实现一个自己的日期选择组件吧。案例地址
我们首先需要分析一下,一个日期组件需要准备哪些东西。
1、日期输入框
2、日期选择面板、星期显示
3、年份、月份选择
输入框我就不展示了,日期选择面板可以长这样子。
我相信实现这样的一个 UI 是非常简单的,那么重要的就是展示数据以及交互效果。
组件在使用的时候应该是使用 v-model 的,那么在我们的组件就就可以通过 props 取到这个值。
props{
//v-model的取值
value:{
type:String,
default:'1990-01-15' //哈哈,这是我生日,如果你v-model属性都没有就会显示了
}
}
那么对于组件本身,需要准备一些自己的属性。
data(){
return{
currentValue:'', //当前值
zIndex:-1, //当前面板的z-index
isShow:false, //是否显示日期面板
select:'date', //当前的操作项 date、year、month(暂时没做)
weekArray:['日','一','二','三','四','五','六'],
currentDate:[], //当前日期
dateArray:[], //当月日期列表
firstDate:[], //当月1号
yearList:[] //当前年列表
}
}
注释已经说明这些值的作用,不过还有一点需要注意的是,我对于日期是通过一个数组来组织的,比如 2018-06-06 ,对应的日期就是 [2018,06,06] ,这样的可以比较方便的操作每个日期的年月日。
那么,接下来就是初始化组件的时候我们需要初始化这些数据
mounted(){
this.initData();
},
//初始化值
initData(){
this.currentValue = this.value;
this.currentDate = (this.value||momnet().format('YYYY-MM-DD')).split('-');
this.firstDate = momnet(this.currentDate.join('-')).startOf('month').format('YYYY-MM-DD').split('-');
this.getDateArray();//获取选择面板的日期列表
this.getYearArray();//获取选择面板的年列表
this.getIndex();//获取面板的z-inde 确保是当前最大值+1
},
//获取选择面板的日期列表方法
getDateArray(){
let day = momnet(this.firstDate.join('-')).day(); //1号是周几
let list = []
for(var i = 0; i < 42; i++){
let date = null;
if(day == 0){
date = momnet(this.firstDate.join('-')).add((i-7),'days');
}else{
date = momnet(this.firstDate.join('-')).add((i-day),'days');
}
list.push(date.format('YYYY-MM-DD').split('-'));
}
this.dateArray = list;
},
//获取当前年列表
getYearArray(){
let year = this.firstDate[0];
let yearList = [];
for(let i = 0; i < 15; i++){
yearList.push(year-7+i);
}
this.yearList = yearList;
},
这里着重了解一下 getDateArray 这个方法,其实思路也是很清晰的。
-
首先获取本月第一天是星期几
-
然后日期面板总共是 6行 * 7列 = 42天,所以得到这42天的日期,只要循环 42 就可以得到,第一天就是: momnet(this.firstDate.join(’-’)).add((i-day),‘days’);
-
然后将得到的 42 天,以数组的形式 [2018,06,06] 的形式组织成一个二维数据 [[2018,06,06],[2018,06,07]…]
-
然后在 template 中循环 dateArray 就可以了。
getYearArray 方法思路也是一样的。只是,我们选择显示 15 年,所以方法在上面。
最后就是页面中的点击交互了
能点击的地方有几处,日期,年前后选择,月前后选择,年选择面板的年,年选择面板的左右切换。基本就这几处了,对应每一个地方的点击,我们做对应的处理。
//获取当前日期 点击日期
clickDate(item){
let date = item.join('-');
this.currentValue = date;
this.$emit('input',date);
this.isShow = false;
},
//点击前一个月
prevMonth(){
let prevMonthDate = momnet(this.firstDate.join('-')).startOf('month').add(-1,'month');
this.firstDate = prevMonthDate.format('YYYY-MM-DD').split('-');
this.getDateArray();
},
//点击下一个月
nextMonth(){
let nextMonthDate = momnet(this.firstDate.join('-')).startOf('month').add(1,'month');
this.firstDate = nextMonthDate.format('YYYY-MM-DD').split('-');
this.getDateArray();
},
//点击前一年
prevYear(){
let prevYearDate = momnet(this.firstDate.join('-')).startOf('month').add(-1,'year');
this.firstDate = prevYearDate.format('YYYY-MM-DD').split('-');
this.getDateArray();
},
//点击下一年
nextYear(){
let nextYearDate = momnet(this.firstDate.join('-')).startOf('month').add(1,'year');
this.firstDate = nextYearDate.format('YYYY-MM-DD').split('-');
this.getDateArray();
},
//点击上一列表年
prevYears(){
let yearList = [];
for(let i = 0; i < this.yearList.length; i++){
yearList.push(this.yearList[i]-15);
}
this.yearList = yearList;
},
//点击下一列表
nextYears(){
let yearList = [];
for(let i = 0; i < this.yearList.length; i++){
yearList.push(this.yearList[i]+15);
}
this.yearList = yearList;
},
//点击年
clickYear(item){
let firstDate = this.firstDate;
firstDate.splice(0,1,item+'');
this.select = 'date';
this.getDateArray();
}
对于每一个点击,对应的处理我就不一一说明了,毕竟代码还是蛮清楚的。
共同学习,写下你的评论
评论加载中...
作者其他优质文章