时间日期五级联动组件封装和demo——微信小程序组件

    xiaoxiao2023-11-25  120

    文章目录

    一、组件需求二、实现思路2.1使用小程序组件进行组装2.2 难点 三、实现3.1 布局文件3.2 js核心代码3.3 最后上调用代码 四、问题(留给你们)五、demo 微信自带的组件只有时间和日期,分开的的组件,所以自己封装了一个时间日期联动的组件

    一、组件需求

    可以传入初始时间,否则就是当前时间可以选择日期时间可以做一些限制,比如选择年份的范围,是否可以选择当前日期之后的日期

    二、实现思路

    2.1使用小程序组件进行组装

    结构如下

    2.2 难点

    个人觉得时间日期的唯一一个坑点是,2月份的瑞年天数变动,实现的方案是,以前在android踩过很多坑,直接把所有数据都直接引入,这样很不便捷,幸好,小程序已经封装好了很多功能,比如滑动监听,让简单化的实现成为可能: 解决方案如下: 在动态的获取中,监听年份和月份的变化,只有当年份和月份发生变化时,才触发更新天数,其中除了2月份,其他的天数均直接写四,代码如下:

    _getMonthDays(year,month) { let that = this; // 优化算法,只有当月份是2月份的时候,才会动态加载 if ([1, 3, 5, 7, 8, 10, 12].includes(month)) { return 31; } else if ([4, 6, 9, 11].includes(month)) { return 30; } else { return new Date(year, month,0).getDate(); // 这个技巧是,获取上月最后一天是上月的第多少天,比如,我们想获取2月份的天数,就传入3月份的第零0天,因为天数是从1开始,那么0就是2月份的最后以一天 } },

    提示一下,月份是从0开始的哦

    三、实现

    3.1 布局文件

    为了实用和美观,我们不仅要实现功能,还要有背景遮罩,定位的底部,先上布局文件.wxml

    <view class='mask' hidden="{{!showDatePick}}"> <view class='content'> <view class='header'> <view class='cancle' bindtap='_cancle'>取消</view> <view class='confirm' bindtap='_confirm'>确定</view> </view> <picker-view indicator-class='select' class='pick-view' value="{{currentDate}}" bindchange="_bindChange"> <picker-view-column> <view class="item" wx:for="{{yearList}}" wx:key="{{index}}">{{item}}年</view> </picker-view-column> <picker-view-column> <view class="item" wx:for="{{monthList}}" wx:key="{{index}}">{{item}}月</view> </picker-view-column> <picker-view-column> <view class="item" wx:for="{{dateList}}" wx:key="{{index}}">{{item}}日</view> </picker-view-column> <picker-view-column> <view class="item" wx:for="{{hourList}}" wx:key="{{index}}">{{item}}时</view> </picker-view-column> <picker-view-column> <view class="item" wx:for="{{minusList}}" wx:key="{{index}}">{{item}}分</view> </picker-view-column> </picker-view> </view> </view>

    应该能看懂,具体的wxss文件可以到github下载查看,最后会贴上demo

    3.2 js核心代码
    // components/aydk_date_ymdhm/aydk_date_ymdhm.js const MAX_REGION_YEAR = 50;// 默认年的区间是当前时间的开始和结束50年 Component({ /** * 组件的属性列表 */ properties: { // isAfter:{ // 是否允许选择当前日期之后的日期 之后优化再做,谁有兴趣可以优化一下 // type:Boolean, // value: false // }, initDate:{ //初始化时间,格式是string,可以被new Date(param) 初始化的时间 type:String, value: new Date().getTime() }, showDatePick:{ type: Boolean, value: false, observer: function (newVal, oldVal) { // 属性值变化时执行 let that = this; if(newVal){ that._initCurrentDate(); } } } }, /** * 组件的初始数据 */ data: { showDatePick: false, currentDate: [0,0,0,0,0], yearList: [], monthList: [], dateList: [], hourList: [], //代码初始化 minusList: [] // 代码初始化 }, //初始化写到挂载事件中,不能写到create钩子里 attached() { let that = this; that._initCurrentDate(); that._initHour(); that._initMinus(); }, // 为了保证数据初始化完成 ready() { let that = this; that.setData({ currentDate: that.data.currentDate }) }, /** * 组件的方法列表 */ methods: { /** * 函数调用,可选 * @date 初始化时间,可选 */ showDate(date){ let that = this; if(date) { this.initDate = date; } that._initCurrentDate(); that.setData({ showDatePick: true }) }, /** * 初始化开始时间 */ _initCurrentDate() { let that = this; let now = new Date(that.data.initDate); that.data.currentDate[1] = now.getMonth(); // 初始化月份 that.data.currentDate[2] = now.getDate()-1; // 初始化天 that.data.currentDate[3] = now.getHours(); // 初始化小时 that.data.currentDate[4] = now.getMinutes(); // 初始化分钟 that._initYear(now.getFullYear()); // 初始化年 that._initMonth(); // 初始化月份 that._initDate(now.getFullYear(), now.getMonth()+1); // 初始化天 }, /** * 初始化年滚动 * 参数为当前年 */ _initYear(year) { let that = this; that.data.yearList = []; for (let orgion = 0; orgion < MAX_REGION_YEAR; orgion++){ if(year-orgion>=1970){ that.data.yearList.unshift(year-orgion); } that.data.yearList.push(orgion+year+1);// 当前年份已经push了 } that.data.currentDate[0] = that.data.yearList.indexOf(year); that.setData({ currentDate: that.data.currentDate, yearList: that.data.yearList }) }, _initMonth(){ let that = this; that.setData({ monthList:Array.from(Array(12), (v,k)=>(k+1)) }) }, _initDate(year,month) { let that = this; that.setData({ dateList: Array.from(Array(that._getMonthDays(year,month)), (v, k) => (k + 1)) }) }, _initHour() { let that = this; that.setData({ hourList: Array.from(Array(24), (v, k) => k) }) }, _initMinus() { let that = this; that.setData({ minusList: Array.from(Array(60), (v, k) => k) }) }, _getMonthDays(year,month) { let that = this; // 优化算法,只有当月份是2月份的时候,才会动态加载 if ([1, 3, 5, 7, 8, 10, 12].includes(month)) { return 31; } else if ([4, 6, 9, 11].includes(month)) { return 30; } else { return new Date(year, month,0).getDate(); } }, _bindChange(e){ let that = this; if (e.detail.value[0] !== that.data.currentDate[0] || e.detail.value[1] !== that.data.currentDate[1]) { that._initDate(that.data.yearList[e.detail.value[0]], that.data.monthList[e.detail.value[1]]); } that.data.currentDate = e.detail.value; }, _cancle(){ let that = this; that.setData({ showDatePick: false }) }, _confirm(){ let that = this; that.setData({ showDatePick: false }) that.triggerEvent('getDate', [that.data.yearList[that.data.currentDate[0]], that.data.monthList[that.data.currentDate[1]],that.data.dateList[that.data.currentDate[2]],that.data.hourList[that.data.currentDate[3]],that.data.minusList[that.data.currentDate[4]]]); } } })
    3.3 最后上调用代码
    //先在json中声明 "usingComponents": { "date":"../../components/aydk_date_ymdhm/aydk_date_ymdhm" } // 使用代码 ,这只是最基本的调用 <date showDatePick='{{showDatePick}}' bind:getDate="getDateData"> </date>

    四、问题(留给你们)

    写的时候为求速度,到快写完发现准备加上点击遮罩关闭组件,但是发现布局设计的不太合理,没办法加,还有就是最后的返回数据,应该可以返回数组和时间,让调用更傻瓜点。 好啦,基本结束啦

    五、demo

    组件demo

    欢迎加群交流哦

    最新回复(0)