微信小程序自定義時(shí)間段picker選擇器
本文實(shí)例為大家分享了微信小程序自定義時(shí)間段picker選擇器的具體代碼,供大家參考,具體內(nèi)容如下
想實(shí)現(xiàn)一個(gè)可以選擇年份和時(shí)間段的日期選擇器,如下所示
微信小程序自帶的picker組件雖然能實(shí)現(xiàn)如上的內(nèi)容,但不能實(shí)現(xiàn)樣式的修改,不太符合小程序的設(shè)計(jì)主題,所以考慮了以下兩種方法來(lái)實(shí)現(xiàn)如上的設(shè)計(jì)。
1.自定義date-picker
把要實(shí)現(xiàn)的date-picker封裝為一個(gè)組件,組件內(nèi)套用小程序自帶的picker-view組件,其中picker_view-column表示不同的選擇列,這樣可以方便地實(shí)現(xiàn)樣式的自定義。
實(shí)現(xiàn)效果:
具體實(shí)現(xiàn)
wxml文件:
<view class="mask" wx:if="{{isShow}}" catchtap="cancel"> ? <view class="content" style="height:800rpx" animation="{{animation}}"> ? ? <view class="top"> ? ? ? <view class="top-text top-left-color" hover-class="top-left-color-hover" catchtap="cancel">取消</view> ? ? ? <view class="top-text top-right-color" hover-class="top-right-color-hover" catchtap="confirm">確定</view> ? ? </view> ? ? <picker-view style="width: 100%; height: 80%;" value="{{value}}" bindchange="change" catchtap="no"> ? ? ? <picker-view-column> ? ? ? ? <view wx:for="{{date_list}}" wx:key="date_list" class="item">{{item}}</view> ? ? ? </picker-view-column> ? ? ? <picker-view-column> ? ? ? ? <view wx:for="{{time_list}}" wx:key="time_list" class="item">{{item}}</view> ? ? ? </picker-view-column> ? ? </picker-view> ? </view> </view>
wxss文件:
.mask { ? position: fixed; ? width: 100%; ? height: 100%; ? left: 0; ? right: 0; ? top: 0; ? bottom: 0; ? display: flex; ? background-color: rgba(0, 0, 0, 0.7); ? z-index: 9999; ? flex-direction: column; ? justify-content: flex-end; } .content { ? display: flex; ? flex-direction: column; ? width: 100%; ? background: white; ? border-top-right-radius: 20rpx; ? border-top-left-radius: 20rpx; } .top { ? display: flex; ? flex-direction: row; ? justify-content: space-between; ? align-items: center; ? height: 100rpx; ? border-bottom: 1rpx solid #d3cfcf; } .top-text { ? font-size: 30rpx; ? width: 150rpx; ? height: 100rpx; ? display: flex; ? flex-direction: row; ? justify-content: center; ? align-items: center; } .top-left-color { ? color: #878787; } .top-left-color-hover { ? color: #f1eaea; } .top-right-color { ? color: #1296DB; } .top-right-color-hover { ? color: #82ccf3; } .item { ? width: 100%; ? align-items: center; ? justify-content: center; ? display: flex; ? flex-direction: row; ? font-size: 18px; }
Component({ ? ? /** ? ? ?* 組件的屬性列表 ? ? ?*/ ? ? properties: { ? ? ? ? range: { //可預(yù)約的日期范圍。默認(rèn)日期從今天開(kāi)始,到第range天后為止,這里設(shè)為10天 ? ? ? ? ? ? type: Number, ? ? ? ? ? ? value: 10 ? ? ? ? }, ? ? ? ? start_time: { //開(kāi)始時(shí)間,設(shè)為整點(diǎn) ? ? ? ? ? ? type: Number, ? ? ? ? ? ? value: 8 ? ? ? ? }, ? ? ? ? step: { //預(yù)約時(shí)間的步長(zhǎng),設(shè)置為30,表示30分鐘 ? ? ? ? ? ? type: Number ? ? ? ? }, ? ? ? ? end_time: { //結(jié)束時(shí)間,設(shè)為整點(diǎn) ? ? ? ? ? ? type: Number, ? ? ? ? ? ? value: 22 ? ? ? ? } ? ? }, ? ? /** ? ? ?* 組件的初始數(shù)據(jù) ? ? ?*/ ? ? data: { ? ? ? ? isShow: false, ? ? ? ? selectDate: "", ? ? ? ? dialogh: 0, ? ? ? ? //日期列表和時(shí)間列表 ? ? ? ? date_list: [], ? ? ? ? time_list: [] ? ? }, ? ? attached: function () { ? ? ? ? let start_day = this.ts_string(new Date().getTime()); ? ? ? ? console.log(start_day); //2021-08-31 ? ? ? ? console.log(new Date()); ? ? ? ? let end_day = this.ts_string(new Date().setDate(new Date().getDate() + this.properties.range)) ? ? ? ? //獲取日期列表 ? ? ? ? let date_list = this.getDiffDate(start_day, end_day); ? ? ? ? //獲取時(shí)間列表 ? ? ? ? let time_list = this.getTimeList(this.properties.start_time, this.properties.end_time, this.properties.step); ? ? ? ? console.log(time_list); ? ? ? ? this.setData({ ? ? ? ? ? ? // date_time: [date_column, time_column], ? ? ? ? ? ? date_list: date_list, ? ? ? ? ? ? time_list: time_list, ? ? ? ? }) ? ? ? ? //動(dòng)畫 ? ? ? ? this.animation = wx.createAnimation({ ? ? ? ? ? ? duration: 300 ? ? ? ? }) ? ? ? ? //500rpx轉(zhuǎn)成px ? ? ? ? let dialoghpx = 800 / 750 * wx.getSystemInfoSync().windowWidth ? ? ? ? this.setData({ ? ? ? ? ? ? dialogh: dialoghpx, ? ? ? ? ? ? selectDate: this.data.date_list[0] + this.data.time_list[0] ? ? ? ? }) ? ? }, ? ? methods: { ? ? ? ? getDiffDate(start, end) { ? ? ? ? ? ? let startTime = new Date(start); ? ? ? ? ? ? let endTime = new Date(end); ? ? ? ? ? ? let dateArr = []; ? ? ? ? ? ? while ((endTime.getTime() - startTime.getTime()) >= 0) { ? ? ? ? ? ? ? ? dateArr.push(this.ts_string(startTime.getTime())); ? ? ? ? ? ? ? ? startTime.setDate(startTime.getDate() + 1); ? ? ? ? ? ? } ? ? ? ? ? ? return dateArr; ? ? ? ? }, ? ? ? ? zfill(num, length) { ? ? ? ? ? ? return (Array(length).join('0') + num).slice(-length); ? ? ? ? }, ? ? ? ? //把日期轉(zhuǎn)換成xxxx-xx-xx的形式 ? ? ? ? ts_string(timestamp) { ? ? ? ? ? ? let d = new Date(timestamp); ? ? ? ? ? ? let day = ""; ? ? ? ? ? ? switch (d.getDay()) { ? ? ? ? ? ? ? ? case 1: ? ? ? ? ? ? ? ? ? ? day = "周一"; ? ? ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? ? ? case 2: ? ? ? ? ? ? ? ? ? ? day = "周二"; ? ? ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? ? ? case 3: ? ? ? ? ? ? ? ? ? ? day = "周三"; ? ? ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? ? ? case 4: ? ? ? ? ? ? ? ? ? ? day = "周四"; ? ? ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? ? ? case 5: ? ? ? ? ? ? ? ? ? ? day = "周五"; ? ? ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? ? ? case 6: ? ? ? ? ? ? ? ? ? ? day = "周六"; ? ? ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? ? ? case 0: ? ? ? ? ? ? ? ? ? ? day = "周日"; ? ? ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? } ? ? ? ? ? ? let string = (d.getFullYear()) + "-" + ? ? ? ? ? ? ? ? this.zfill((d.getMonth() + 1), 2) + "-" + ? ? ? ? ? ? ? ? this.zfill((d.getDate()), 2) + " (" + day + ")" ? ? ? ? ? ? return string ? ? ? ? }, ? ? ? ? //獲取時(shí)間區(qū)間列表,輸入(起始時(shí)間,結(jié)束時(shí)間,步長(zhǎng)) ? ? ? ? getTimeList(start, end, step) { ? ? ? ? ? ? let start_time = new Date(); ? ? ? ? ? ? //設(shè)置起始時(shí)間 ? ? ? ? ? ? start_time.setHours(start, 0, 0); ? ? ? ? ? ? console.log(start_time); ? ? ? ? ? ? //設(shè)置結(jié)束時(shí)間 ? ? ? ? ? ? let end_time = new Date(); ? ? ? ? ? ? end_time.setHours(end, 0, 0); ? ? ? ? ? ? let startG = start_time.getTime(); //起始時(shí)間的格林時(shí)間 ? ? ? ? ? ? let endG = end_time.getTime(); //起始時(shí)間的格林時(shí)間 ? ? ? ? ? ? let step_ms = step * 60 * 1000; ? ? ? ? ? ? let timeArr = []; ? ? ? ? ? ? while (startG < endG) { ? ? ? ? ? ? ? ? let time = this.timeAdd(startG, step_ms); ? ? ? ? ? ? ? ? timeArr.push(time); ? ? ? ? ? ? ? ? startG += step_ms; ? ? ? ? ? ? } ? ? ? ? ? ? return timeArr; ? ? ? ? }, ? ? ? ? timeAdd(time1, add) { ? ? ? ? ? ? var nd = new Date(time1); //創(chuàng)建時(shí)間對(duì)象 ? ? ? ? ? ? //獲取起始時(shí)間的時(shí)分秒 ? ? ? ? ? ? var hh1 = nd.getHours(); ? ? ? ? ? ? var mm1 = nd.getMinutes(); ? ? ? ? ? ? if (hh1 <= 9) hh1 = "0" + hh1; ? ? ? ? ? ? if (mm1 <= 9) mm1 = "0" + mm1; ? ? ? ? ? ? nd = nd.valueOf(); //轉(zhuǎn)換為毫秒數(shù) ? ? ? ? ? ? nd = nd + Number(add); ? ? ? ? ? ? nd = new Date(nd); ? ? ? ? ? ? var hh2 = nd.getHours(); ? ? ? ? ? ? var mm2 = nd.getMinutes(); ? ? ? ? ? ? if (hh2 <= 9) hh2 = "0" + hh2; ? ? ? ? ? ? if (mm2 <= 9) mm2 = "0" + mm2; ? ? ? ? ? ? var time = hh1 + ":" + mm1 + "-" + hh2 + ":" + mm2; ? ? ? ? ? ? return time; //時(shí)間段 ? ? ? ? }, ? ? ? ? change: function (e) { ? ? ? ? ? ? const val = e.detail.value; ? ? ? ? ? ? //val[0]表示選擇的第一列序號(hào),val[1]表示選擇的第二列序號(hào) ? ? ? ? ? ? let select = this.data.date_list[val[0]] + this.data.time_list[val[1]] ? ? ? ? ? ? console.log(select); ? ? ? ? ? ? this.setData({ ? ? ? ? ? ? ? ? selectDate: select ? ? ? ? ? ? }) ? ? ? ? }, ? ? ? ? showDialog() { ? ? ? ? ? ? this.setData({ ? ? ? ? ? ? ? ? isShow: true ? ? ? ? ? ? }) ? ? ? ? ? ? //先向下移動(dòng)dialog高度,然后恢復(fù)原位從而形成從下向上彈出效果 ? ? ? ? ? ? this.animation.translateY(this.data.dialogh).translateY(0).step() ? ? ? ? ? ? this.setData({ ? ? ? ? ? ? ? ? animation: this.animation.export() ? ? ? ? ? ? }) ? ? ? ? }, ? ? ? ? dimsss() { ? ? ? ? ? ? //從原位向下移動(dòng)dailog高度,形成從上向下的收起效果 ? ? ? ? ? ? this.animation.translateY(this.data.dialogh).step() ? ? ? ? ? ? this.setData({ ? ? ? ? ? ? ? ? animation: this.animation.export() ? ? ? ? ? ? }) ? ? ? ? ? ? //動(dòng)畫結(jié)束后蒙層消失 ? ? ? ? ? ? setTimeout(() => { ? ? ? ? ? ? ? ? this.setData({ ? ? ? ? ? ? ? ? ? ? isShow: false ? ? ? ? ? ? ? ? }) ? ? ? ? ? ? }, 300) ? ? ? ? }, ? ? ? ? cancel() { ? ? ? ? ? ? this.triggerEvent("cancel") ? ? ? ? ? ? this.dimsss() ? ? ? ? }, ? ? ? ? confirm() { ? ? ? ? ? ? this.triggerEvent("confirm", { ? ? ? ? ? ? ? ? selectDate: this.data.selectDate ? ? ? ? ? ? }) ? ? ? ? ? ? this.dimsss() ? ? ? ? } ? ? } })
組件的使用
想在父組件中使用封裝好的date-picker組件,先要在父組件的json文件中聲明。
{ ? "usingComponents": { ? ? "date-picker": "../../components/date-picker/date-picker" ? }, }
如果想實(shí)現(xiàn)簡(jiǎn)單的選擇時(shí)間段并在頁(yè)面中顯示的功能,父組件代碼如下編寫即可。
父組件wxml文件:
<view class="option" bindtap="timeOpen" style="font-size: 16px;"> ? ? ? {{selectDate}} </view> <date-picker id="picker" range="8" step="40" bindconfirm="confirm"></date-picker>
父組件js文件:
Page({ ? ? data: { ? ? ? ? selectDate: "", ? ? ? ? machineShow: false, ? ? }, ? ? onLoad: function () { ? ? ? ? this.picker = this.selectComponent("#picker") ? ? }, ? ? timeOpen() { ? ? ? ? this.picker.showDialog(); ? ? }, ? ? confirm(e) { ? ? ? ? this.setData({ ? ? ? ? ? ? selectDate: e.detail.selectDate ? ? ? ? }) ? ? }, })
2.結(jié)合vant weapp的date-picker
自定義定義的date-picker組件已經(jīng)可以實(shí)現(xiàn)想實(shí)現(xiàn)的功能,但自定義的組件樣式不夠美觀。這時(shí),我注意到了小程序可以使用vant的組件庫(kù),組件庫(kù)多列選擇器的樣式可以自由修改,而且自帶樣式已經(jīng)足夠美觀,所以下面考慮結(jié)合vant組件庫(kù)實(shí)現(xiàn)date-picker。
實(shí)現(xiàn)效果
具體實(shí)現(xiàn)
使用vant weapp的picker組件和popup組件可以更簡(jiǎn)潔地實(shí)現(xiàn)想要的效果,打造自定義的date-picker組件。
首先需要在編寫組件的json文件中導(dǎo)入vant weapp的相應(yīng)組件
{ ? ? "component": true, ? ? "usingComponents": { ? ? ? ? "van-picker": "@vant/weapp/picker/index", ? ? ? ? "van-popup": "@vant/weapp/popup/index" ? ? } }
然后編寫date-picker的wxml文件:
<van-popup round show="{{ isShow }}" bind:close="cancel" position="bottom" custom-style="height: 55%"> ? <van-picker show-toolbar columns="{{ date_time_list }}" bind:cancel="cancel" bind:change="change" ? ? bind:confirm="confirm" /> </van-popup>
因?yàn)関an-picker的參數(shù)columns接受的是一個(gè)對(duì)象數(shù)組,與picker-view有一定差異,所以需要將date-picker的js文件進(jìn)行如下更改。
1.修改data,增加date_time_list
data: { ? ? ? ? isShow: false, ? ? ? ? selectDate: "", ? ? ? ? dialogh: 0, ? ? ? ? //日期列表和時(shí)間列表 ? ? ? ? date_list: [], ? ? ? ? time_list: [], ? ? ? ? date_time_list: [] ?//增加的字段 ? ? },
2.修改attached函數(shù)
//增加的內(nèi)容 let date_time_list = [{ ? ? ? ? ? ? ? ? values: date_list ? ? ? ? ? ? }, ? ? ? ? ? ? { ? ? ? ? ? ? ? ? values: time_list ? ? ? ? ? ? ? } ? ? ? ? ]; ? ? ? ? this.setData({ ? ? ? ? ? ? date_list: date_list, ? ? ? ? ? ? time_list: time_list, ? ? ? ? ? ? date_time_list: date_time_list ?//增加的內(nèi)容 ? ? ? ? })
3.修改change函數(shù)
change: function (e) { ? ? ? ? ? ? let val = e.detail.value; ? ? ? ? ? ? let select = val[0] + val[1]; ? ? ? ? ? ? this.setData({ ? ? ? ? ? ? ? ? selectDate: select ? ? ? ? ? ? }) ? ? ? ? },
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
常用的Javascript設(shè)計(jì)模式小結(jié)
javascript設(shè)計(jì)模式有很多種,本文給大家介紹常用的javascript設(shè)計(jì)模式,對(duì)javascript設(shè)計(jì)模式相關(guān)知識(shí)感興趣的朋友一起學(xué)習(xí)吧2015-12-12js/jquery遍歷對(duì)象和數(shù)組的方法分析【forEach,map與each方法】
這篇文章主要介紹了js/jquery遍歷對(duì)象和數(shù)組的方法,結(jié)合實(shí)例形式分析了數(shù)組遍歷的forEach,map與each方法常見(jiàn)使用技巧,需要的朋友可以參考下2019-02-02myFocus slide3D v1.1.0 使用方法與下載
myFocus slide3D v1.1.0 使用方法與下載,需要的朋友可以參考下。2011-01-01微信小程序圖片自適應(yīng)實(shí)現(xiàn)解析
這篇文章主要介紹了微信小程序圖片自適應(yīng)實(shí)現(xiàn)解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-01-01TypeScript中import?type與import的區(qū)別詳析
ES6引入了模塊化,其設(shè)計(jì)思想是在編譯時(shí)就能確定模塊的依賴關(guān)系,以及輸入和輸出的變量,下面這篇文章主要給大家介紹了關(guān)于TypeScript中import?type與import區(qū)別的相關(guān)資料,需要的朋友可以參考下2022-07-07headjs實(shí)現(xiàn)網(wǎng)站并行加載但順序執(zhí)行JS
本文主要介紹如何使用head.js實(shí)現(xiàn)網(wǎng)站并行加載但順序執(zhí)行JS,提高網(wǎng)站加載速度。需要的朋友可以看下2016-11-11JavaScript使用pop方法移除數(shù)組最后一個(gè)元素用法實(shí)例
這篇文章主要介紹了JavaScript使用pop方法移除數(shù)組最后一個(gè)元素,實(shí)例分析了javascript中pop方法的使用技巧,需要的朋友可以參考下2015-04-04JS擴(kuò)展String.prototype.format字符串拼接的功能
這篇文章主要介紹了JS擴(kuò)展String.prototype.format字符串拼接的功能,需要的朋友可以參考下2018-03-03jquery將標(biāo)簽元素的高設(shè)為屏幕的百分比
這篇文章主要介紹了js將標(biāo)簽元素的高設(shè)為屏幕的百分比,需要的朋友可以參考下2017-04-04