文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

小程序日期(日历)时间 选择器组件

2023-09-01 17:40

关注

封装一个小程序日期(日历)时间 选择器组件

简要说明:
一共两个版本 ,date-time-picker 和 date-time-picker-plus.
date-time-picker 弹窗层是 基于 vant-weappvan-popup 组件实现的
date-time-picker-plus 弹窗层是 基于 小程序 自带的 page-container 组件来实现的
*注意:date-time-picker 需要下载 vant-weapp 组件库配合一起使用,date-time-picker-plus 可以直接在小程序里面使用

首先看一下效果图

请添加图片描述

组件代码

两个版本代码几乎一样,只是弹窗层用的不一样,这里我就用 基于 vant-weapp UI一起使用的版本来写

<view class="date-time-picker-box">  <van-popup show="{{ show }}" zIndex="9999" round position="bottom" custom-style="border-radius:16px 16px 0 0;min-height:355px;max-height:400px;" bind:close="handleCancel">    <view class="date-time-picker-title">      <view class="date-time-picker-nav">        <view bindtap="handleChangeTag" data-index="0" class="tag date-tag {{currentIndex == 0 ? 'active' : ''}}">          {{year}}{{month}}{{day}}</view>        <view bindtap="handleChangeTag" data-index="1" class="tag time-tag {{currentIndex == 1 ? 'active' : ''}}">          {{hour}}:{{minute}}        </view>        <view class="date-time-line" style="left:{{left}}px;width: {{width}}px;"></view>      </view>      <button bindtap="handleConfirm" class="date-picker-oper-btn">确定</button>    </view>    <view class="date-time-picker-content">      <!-- 日历主体 -->      <swiper current="{{currentIndex}}" style="height:100%;">        <swiper-item catchtouchmove="catchtouchmove">          <view class="swiper-item ">            <!-- 日历组件 -->            <calendar bindselectDay="selectDay" bindgetDateList="getDateList" vertical="{{vertical}}"></calendar>          </view>        </swiper-item>        <swiper-item catchtouchmove="catchtouchmove">          <view class="swiper-item ">            <div class="date-time-item">              <picker-view indicator-style="height: 50px;" style="width: 100%; height: 200px;text-align:center;" value="{{value}}" bindpickstart="bindpickstart" bindpickend="bindpickend" bindchange="bindChange">                <picker-view-column>                  <view wx:for="{{hours}}" wx:key="*this" style="line-height: 50px">{{item}}</view>                </picker-view-column>                <picker-view-column>                  <view wx:for="{{minutes}}" wx:key="*this" style="line-height: 50px">                    {{item}}</view>                </picker-view-column>              </picker-view>            </div>          </view>        </swiper-item>      </swiper>    </view>  </van-popup></view>
.date-time-picker-box .date-time-picker-title {  display: flex;  align-items: center;  justify-content: space-between;  padding: 0rpx 48rpx;  height: 112rpx;  box-sizing: border-box;  border-bottom: 2rpx solid #E5E3E3;  max-height: 400px;  }.date-time-picker-box .date-time-picker-title .title-txt {  font-size: 17px;  font-weight: 500;  color: #1F1E1E;}.date-time-picker-box .date-time-picker-title .date-picker-oper-btn {  width: 104rpx;  height: 64rpx;  line-height: 64rpx;  text-align: center;  font-size: 28rpx;  border-radius: 8rpx;  font-weight: 500;  margin: 0;  padding: 0;  color: var(--themeTxtColor);  background-color: var(--themeColor);}.date-time-picker-box .date-time-picker-title .cancel-btn {  color: #5C5959;  background-color: #fff;  text-align: left;}.date-time-picker-box .date-time-picker-title .date-time-picker-nav {  position: relative;  display: flex;  align-items: center;  font-weight: 500;  color: #8F8D8D;  height: 100%;}.date-time-picker-box .date-time-picker-nav .date-tag {  margin-right: 32rpx;}.date-time-picker-box .date-time-picker-nav .tag {  height: 100%;  display: flex;  align-items: center;  justify-content: center;}.date-time-picker-box .date-time-picker-nav .tag.active {  color: #1F1E1E;}.date-time-picker-box .date-time-picker-nav .date-time-line {  position: absolute;  bottom: 0;  width: 40rpx;  height: 4rpx;  background-color: #5C5959;  transition: all 0.3s linear;}.date-picker-btn-box {  display: flex;  font-weight: 600;  margin-top: 40rpx;  color: var(--themeColor);  justify-content: space-around;}.date-time-picker-content {  height: 600rpx;  box-sizing: border-box;}
{  "component": true,  "usingComponents": {    "van-popup": "@vant/weapp/popup/index",    "calendar":"./calendar/index"  }}
const date = new Date(); // 获取系统日期var getYear = date.getFullYear(),  getMonth =    date.getMonth() + 1 < 10      ? "0" + (date.getMonth() + 1)      : date.getMonth() + 1,  getDate = date.getDate() < 10 ? "0" + date.getDate() : date.getDate(),  isScroll = false;Component({  properties: {    show: {      // 控制弹窗显示和隐藏      type: Boolean,      value: false,    },    vertical: {      // 是否垂直滑动      type: Boolean,      value: false,    },        type: {      type: String,      value: "part", // time 和 part    },  },  data: {    year: getYear, // 当前已选年份,默认是当年    month: getMonth, // 当前已选月份,默认是当月    day: getDate, // 当前已选天,默认是当天    hour: "09", // 当前已选小时, 默认 09 点    minute: "00", // 当前已选分钟,默认00    hours: [], // 时间选择器,存放的小时数组 0 - 23    minutes: [], // 时间选择器,存放的分钟数组 00 和 30 或者 00 - 59    value: [0, 0], // 时间选择器,当前选择时间 索引    currentIndex: 0, // tab导航当前索引    left: 0, // tab导航 底部线条 当前离左侧位置 距离    width: 123, // tab导航 底部线条 当前 宽度    firstEnter: true, // 是否第一次打开, 默认true  },  lifetimes: {    attached: function () {      this.initDateTimePicker();    },    moved: function () {},    detached: function () {},  },  methods: {    // 日期改变的回调    selectDay({ detail }) {      console.log(detail, "selectDay detail");      let { year, month, day } = detail;      month = month > 9 ? month : "0" + month;      day = day > 9 ? day : "0" + day;      if (!this.data.firstEnter) {        setTimeout(() => {          this.setData({ currentIndex: 1 });          this.changeline();        }, 300);      }      this.setData({ year, month, day, firstEnter: false });    },    // 切换导航    handleChangeTag(e) {      this.setData({        currentIndex: e.currentTarget.dataset.index,        firstEnter: false,      });      this.changeline();    },    // 渲染横线位置的方法    changeline() {      let _this = this;      // SelectorQuery.in(Component component): 将选择器的选取范围更改为自定义组件 component 内      let query = wx.createSelectorQuery().in(this);      // select() 在当前页面下选择第一个匹配选择器 selector 的节点      // boundingClientRect() 添加节点的布局位置的查询请求。相对于显示区域,以像素为单位      query.select(".active").boundingClientRect();      // SelectorQuery.exec(function callback) 执行所有的请求      // 请求结果按请求次序构成数组,在callback的第一个参数中返回      query.exec(function (res) {        // console.log(res);        _this.setData({          left: res && res[0].left - 24,          width: parseInt(res[0].width),        });      });    },        bindChange(e) {      const val = e.detail.value;      this.setData({        hour: this.data.hours[val[0]],        minute: this.data.minutes[val[1]],      });    },    // 滚动开始    bindpickstart() {      isScroll = true;    },    //滚动结束    bindpickend() {      isScroll = false;    },    // 点击取消按钮,关闭日期选择器    handleCancel() {      this.setData({ show: false });    },    // 点击确定按钮    handleConfirm() {      let { year, month, day, hour, minute } = this.data;      // console.log(year, month, day, hour,  minute)      // 判断用户选择时间滚动是否结束,解决 picker-view bindChange 延迟问题      if (isScroll) return;      const timeStr =        year + "-" + month + "-" + day + " " + hour + ":" + minute;      this.triggerEvent("onSelectDate", timeStr);      this.setData({ show: false, currentIndex: 0 });      this.changeline();    },    // 初始化 picker 时间数据    initDateTimePicker() {      let hours = [],        minutes = [];      // 存放小时的数组      for (let i = 0; i <= 23; i++) {        if (i < 10) {          i = "0" + i;        }        hours.push(i);      }      // 存放分钟的数组      if (this.data.type === 'time') {        for (let i = 0; i <= 59; i++) {          if (i < 10) { i = '0' + i }          minutes.push(i)        }      } else {        minutes = ['00', '30']      }      this.setData({ hours, minutes });      this.setData({ value: [9, 0] });    },    // 加载日历数据    getDateList() {      // 防止滑动时 tab导航切换到时间模块      this.setData({ firstEnter: true });    },    // 禁止 日期时间 swiper 滑动    catchtouchmove() {      return false;    },  },});

简要说明:
在 index.wxml 文件 中 ,会有一个 日历组件

这个组件会放在 date-time-picker 组件目录下,这里我就不把代码贴出来了,可以直接去我的远程仓库去拉取。
组件代码仓库地址:Gitee | Github 或者直接复制下面的链接 直接下载代码

git clone https://gitee.com/junfeng535/wx-date-time-picker.git
git clone https://github.com/junfeng-git/wx-date-time-picker.git

来源地址:https://blog.csdn.net/m0_49045925/article/details/129195068

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     807人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     351人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     314人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     433人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     221人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-移动开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯