封装小程序日期选择器组件 picker-view

  1. 效果图
    封装小程序日期选择器组件 picker-view_第1张图片

  2. 日期组件中

  • wxml 部分
<view>
    <view bindtap="handleShowDatePicker">{{year}}-{{month}}<text wx:if="{{isShowDays}}">-{{day}}</text></view>
</view>
<view class="date-picker-container {{isShow ? 'active' : 'display-none'}}">
    <view class="date-picker-title">日期选择器</view>
    <picker-view indicator-style="height: 50px;" style="width: 100%; height: 200px;text-align:center;" value="{{currentValue}}" bindpickstart="bindpickstart" bindpickend="bindpickend" bindchange="bindChange">
        <picker-view-column>
            <view wx:for="{{years}}" wx:key="*this" style="line-height: 50px">{{item}}</view>
        </picker-view-column>
        <picker-view-column>
            <view wx:for="{{months}}" wx:key="*this" style="line-height: 50px">{{item}}</view>
        </picker-view-column>
        <picker-view-column wx:if="{{isShowDays}}">
            <view wx:for="{{days}}" wx:key="*this" style="line-height: 50px">{{item}}</view>
        </picker-view-column>
    </picker-view>
    <view class="date-picker-btn-box">
      <view bindtap="cancel" class="date-picker-cancel-btn">取消</view>
      <view bindtap="confirm" class="date-picker-confirm-btn">确定</view>
    </view>
</view>
<view class='mask' wx:if="{{isShow}}" bindtap='closeModal'></view>

  • wxss 部分
.mask{
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    z-index: 99999;
    background-color: rgba(0, 0, 0, .5);
  }
  
  .date-picker-container {
    width: 100%;
    position: absolute;
    bottom: 0; 
    left: 0;
    z-index: 100000;
    padding: 40rpx 60rpx;
    transition: ease .3s;
    transform: translateY(100%);  
    background-color: #fff;
    box-sizing: border-box;
    border-radius: 30rpx 30rpx 0 0;
  }
  .display-none{
    display: none;
  }
  .date-picker-container.active{
    transform: translateY(0);
    display: block;
  }
  .date-picker-title {
    text-align: center;
  }
  .date-picker-btn-box {
    display: flex;
    font-weight: 600;
    margin-top: 40rpx;
    color: var(--themeColor);
    justify-content: space-around;
  }
  .date-picker-btn-box .date-picker-cancel-btn, 
  .date-picker-btn-box .date-picker-confirm-btn {
    text-align: center;
    font-size: 32rpx;
    padding: 0 96rpx;
    height: 88rpx;
    line-height: 88rpx;
    border-radius: 12rpx;
    color: var(--themeColor);
    border: 2rpx solid var(--themeColor);
  }
  .date-picker-btn-box .date-picker-confirm-btn{
    color: #fff;
    background-color: var(--themeColor);
  }
  • js 部分
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: {
    // 是否显示 日
    isShowDays: {
      type: Boolean,
      value: true
    },
    /**
     * 日期选择器默认值 
     * 1. 这里设置无效 (暂时不知道什么原因)  --- 问题
     * 2. 所以由父组件传值过来,(* 父组件中,在 onShow() 这个生命周期中就 setData()) --- 解决
     */
    currentValue: {
      type: Array,
      value: [9999,0,0]
    },
  },
  data: {
      isShow: true,
      year:getYear,
      month: getMonth,
      day: getDate,
      years: [], 
      months: [],
      days: []
  },
  lifetimes: {
      attached: function () {
        this.initDatePicker();
      },
      moved: function () {},
      detached: function () {},
  },
  methods: {
    /***
     * 滚动选择时触发change事件,
     * 可以查看小程序官方文档了解
     */
    bindChange(e) {
      const val = e.detail.value;
      // console.log(val)
      this.setData({
        year: this.data.years[val[0]],
        month: this.data.months[val[1]],
        day: this.data.days[val[2]]
      })
      const { year, month } = this.data
      const days = this.getOneMonthCountDaysArr(year, month)
      this.setData({ days })
    },
    // 获取某个月中有多少天数,并存到一个数组中
    getOneMonthCountDaysArr(year,month) {
      let dayLen = new Date(year, Number(month), 0).getDate(); // 获取当前月有多少天
      let daysArr = []
      for (let i = 1; i <= dayLen; i++) {
        if (i < 10) { i = '0' + i }
        daysArr.push(i)
      }
      return daysArr
    },
    // 滚动开始
    bindpickstart(){
      isScroll = true
    },
    //滚动结束
    bindpickend(){
      isScroll = false
    },
    // 点击日期,显示日期选择器
    handleShowDatePicker() {
      this.setData({isShow: true})
    },
    // 点击取消按钮,关闭日期选择器
    cancel() {
      this.setData({isShow: false})
    },
    // 点击确定按钮
    confirm() {
      let { year, month, day } = this.data
      // 判断用户选择时间滚动是否结束,解决 picker-view bindChange 延迟问题
      if (isScroll) return
      this.triggerEvent('handleSelectDate', { year, month ,day })
      this.setData({isShow: false})
    },
    // 点击遮罩层,关闭日期选择器
    closeModal() {
      this.setData({isShow: false})
    },
    // 初始化 picker 日期数据
    initDatePicker() {
        const date = new Date(),
               years = [],
               months = [],
               days = this.getOneMonthCountDaysArr(date.getFullYear(), (date.getMonth() + 1)) || [];  // 获取当前月有多少天
        // 存放年份的数组
        for (let i = 2010; i <= date.getFullYear(); i++) {
            years.push(i)
        }
        // 存放月份的数组
        for (let i = 1; i <= 12; i++) {
            if (i < 10) { i = '0' + i }
            months.push(i)
        }
        this.setData({ years, months, days })
    },
  },
});
  • json 部分 (默认)
{
  "component": true,
  "usingComponents": {}
}
  1. 父组件中使用
  • wxml 中
<my-date-picker bind:handleSelectDate="handleSelectDate" currentValue="{{valueList}}"></my-date-picker>
  • js 中
Page({
  /**
   * 页面的初始数据
   */
  data: {
    valueList: [9999,0,0]
  },
  handleSelectDate(e){
    console.log(e.detail);
  },   
  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {

  },
  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady: function () {

  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow: function () {
    const date = new Date()
    this.setData({valueList: [9999,date.getMonth(),date.getDate() -1]})
  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide: function () {

  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload: function () {

  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh: function () {

  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom: function () {

  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage: function () {

  }
})
  • json 中
{
  "usingComponents": {
    "my-date-picker": "/component/my-date-picker/index"
  },
  "navigationBarTitleText": "日期选择器"
}

你可能感兴趣的:(小程序,小程序,javascript,前端)