本文实例为大家分享了微信小程序自定义时间段picker选择器的具体代码,供大家参考,具体内容如下
想实现一个可以选择年份和时间段的日期选择器,如下所示
微信小程序自带的picker组件虽然能实现如上的内容,但不能实现样式的修改,不太符合小程序的设计主题,所以考虑了以下两种方法来实现如上的设计。
1.自定义date-picker
把要实现的date-picker封装为一个组件,组件内套用小程序自带的picker-view组件,其中picker_view-column表示不同的选择列,这样可以方便地实现样式的自定义。
实现效果:
具体实现
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>
- lt;/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: { //可预约的日期范围。默认日期从今天开始,到第range天后为止,这里设为10天
- type: Number,
- value: 10
- },
- start_time: { //开始时间,设为整点
- type: Number,
- value: 8
- },
- step: { //预约时间的步长,设置为30,表示30分钟
- type: Number
- },
- end_time: { //结束时间,设为整点
- type: Number,
- value: 22
- }
- },
- /**
- * 组件的初始数据
- */
- data: {
- isShow: false,
- selectDate: "",
- dialogh: 0,
- //日期列表和时间列表
- 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);
- //获取时间列表
- 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,
- })
- //动画
- this.animation = wx.createAnimation({
- duration: 300
- })
- //500rpx转成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);
- },
- //把日期转换成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
- },
- //获取时间区间列表,输入(起始时间,结束时间,步长)
- getTimeList(start, end, step) {
- let start_time = new Date();
- //设置起始时间
- start_time.setHours(start, 0, 0);
- console.log(start_time);
- //设置结束时间
- let end_time = new Date();
- end_time.setHours(end, 0, 0);
- let startG = start_time.getTime(); //起始时间的格林时间
- let endG = end_time.getTime(); //起始时间的格林时间
- 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); //创建时间对象
- //获取起始时间的时分秒
- var hh1 = nd.getHours();
- var mm1 = nd.getMinutes();
- if (hh1 <= 9) hh1 = "0" + hh1;
- if (mm1 <= 9) mm1 = "0" + mm1;
- nd = nd.valueOf(); //转换为毫秒数
- 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; //时间段
- },
- change: function (e) {
- const val = e.detail.value;
- //val[0]表示选择的第一列序号,val[1]表示选择的第二列序号
- 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
- })
- //先向下移动dialog高度,然后恢复原位从而形成从下向上弹出效果
- this.animation.translateY(this.data.dialogh).translateY(0).step()
- this.setData({
- animation: this.animation.export()
- })
- },
- dimsss() {
- //从原位向下移动dailog高度,形成从上向下的收起效果
- this.animation.translateY(this.data.dialogh).step()
- this.setData({
- animation: this.animation.export()
- })
- //动画结束后蒙层消失
- 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"
- },
- }
复制代码如果想实现简单的选择时间段并在页面中显示的功能,父组件代码如下编写即可。
父组件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.结合vant weapp的date-picker
自定义定义的date-picker组件已经可以实现想实现的功能,但自定义的组件样式不够美观。这时,我注意到了小程序可以使用vant的组件库,组件库多列选择器的样式可以自由修改,而且自带样式已经足够美观,所以下面考虑结合vant组件库实现date-picker。
实现效果
具体实现
使用vant weapp的picker组件和popup组件可以更简洁地实现想要的效果,打造自定义的date-picker组件。
首先需要在编写组件的json文件中导入vant weapp的相应组件 - {
- "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>
复制代码因为van-picker的参数columns接受的是一个对象数组,与picker-view有一定差异,所以需要将date-picker的js文件进行如下更改。
1.修改data,增加date_time_list - data: {
- isShow: false,
- selectDate: "",
- dialogh: 0,
- //日期列表和时间列表
- date_list: [],
- time_list: [],
- date_time_list: [] //增加的字段
- },
复制代码2.修改attached函数 - //增加的内容
- 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 //增加的内容
- })
复制代码3.修改change函数 - change: function (e) {
- let val = e.detail.value;
- let select = val[0] + val[1];
- this.setData({
- selectDate: select
- })
- },
复制代码以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持中国红客联盟。 |