为了账号安全,请及时绑定邮箱和手机立即绑定

Vue.js 日期选择组件实例

标签:
Html5

前言:授人以鱼不如授人以渔,与其寻寻觅觅找一个适合自己UI的选择器控件,不如自己动手,尝试一下。

如果你还不会 Vue.js 那么请移步 Vue.js 官网;如果你已经掌握了如何使用,那么就请跟着我一起实现一个自己的日期选择组件吧。案例地址

我们首先需要分析一下,一个日期组件需要准备哪些东西。

1、日期输入框

2、日期选择面板、星期显示

3、年份、月份选择

image

image

输入框我就不展示了,日期选择面板可以长这样子。

我相信实现这样的一个 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();
}

对于每一个点击,对应的处理我就不一一说明了,毕竟代码还是蛮清楚的。

点击查看更多内容
3人点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
Web前端工程师
手记
粉丝
16
获赞与收藏
263

关注作者,订阅最新文章

阅读免费教程

感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消