温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

微信小程序自定义日期选择器的示例分析

发布时间:2022-01-06 13:07:17 来源:亿速云 阅读:141 作者:柒染 栏目:开发技术

这期内容当中小编将会给大家带来有关微信小程序自定义日期选择器的示例分析,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。

日期选择器是我们在写项目的过程中经常遇到的,有需要标题的选择器,也有不需要标题的选择器

今天给大家带来一个自定义的时间选择器,废话不多说,直接上代码

第一步:先创建一个picker的文件夹

微信小程序自定义日期选择器的示例分析

第二步 :在wxml中写布局样式

<!--picker/picker.wxml-->
<view class="full-box {{isOpen?'cur':''}}">
    <!--<view class="modal" bindtap="tapModal"></view>-->
    <view class="picker">
        <view class="picker-header">
            <view bindtap="cancle" >
                <text>{{cancelText}}</text>
            </view>
            <text >{{titleText}}</text>
            <view bindtap="sure">
                <text   >{{sureText}}</text>
            </view>
        </view>
        <picker-view
            value="{{value}}"
            class="picker-content"
            bindpickstart="_bindpickstart"
            bindchange="_bindChange"
            bindpickend="_bindpickend"
            indicator-
            mask-
        >
            <picker-view-column wx:for="{{columnsData}}" wx:key="{{index}}">
                <view wx:for="{{item}}" wx:for-item="itemIn" class="picker-line" wx:key="{{index}}">
                    <text class="line1">{{isUseKeywordOfShow?itemIn[keyWordsOfShow]:itemIn}}</text>
                </view>
            </picker-view-column>
        </picker-view>
    </view>
</view>

第三步:wxss中添加样式

/* picker/picker.wxss */
.full-box{
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    top: 0;
    z-index: 9999;
    opacity: 0;
    background:rgba(0,0,0,.4);
    transition:all .4s ease-in-out 0;
    pointer-events:none;
}
.full-box.cur{
    opacity:1;
    pointer-events:auto
}
 
.modal{
    position: absolute;
    width: 100%;
    height: 50%;
    bottom:-50%;
    left: 0;
    background: transparent;
    transition:all .4s ease-in-out 0;
}
 
.picker{
    position: absolute;
    width: 100%;
    height: 235px;
    bottom: -235px;
    left: 0;
    background: #fff;
    display: flex;
    flex-direction: column;
    transition:all .4s ease-in-out 0;
}
 
.cur .picker{
    bottom:0;
}
.cur .modal{
    bottom:50%;
}
.picker-line{
    display: flex;
    justify-content: center;
    align-items: center;
}
.picker-header {
    height: 20%;
    box-sizing: border-box;
    padding: 0 20rpx;
    display: flex;
    justify-content: space-between;
    align-items: center;
    border-bottom: 1px solid #eeeeee;
}
.picker-header view {
    height: 100%;
    display: flex;
    justify-content: center;
    align-items: center;
}
.picker-header view text{
    font-size: 36rpx;
}
.picker-content {
    flex-grow: 1;
}
.line1{
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    lines:1
}

第四步:在js中写组件的属性

// picker/picker.js
import { isPlainObject } from './tool'
 
Component({
  /**
   * 组件的属性列表
   */
  properties: {
    scrollType: {
      type: String,
      value: 'normal'// "link": scroll间联动  "normal": scroll相互独立
    },
    listData: {
      type: Array,
      value: [],
      observer: function(newVal) {
        if (newVal.length === 0 || this._compareDate()) return
        this._setTempData()
        const tempArr = [...new Array(newVal.length).keys()].map(() => 0)
        this.data.lastValue = this.data.tempValue = tempArr
        this._setDefault()
 
        // let {defaultPickData} = this.properties;
        // if(newVal.length === 0) return;
        //
        // this._setDefault(newVal, defaultPickData)
      }
    },
    defaultPickData: {
      type: Array,
      value: [],
      observer: function(newVal) {
        if (newVal.length === 0 || this._compareDate()) return
        this._setTempData()
        this._setDefault()
      }
    },
    keyWordsOfShow: {
      type: String,
      value: 'name'
    },
    isShowPicker: {
      type: Boolean,
      value: false,
      observer: function(newVal) {
        if (newVal) {
          this._openPicker()
        } else {
          this._closePicker()
        }
      }
    },
    titleText: {// 标题文案
      type: String,
      value: '请选择到馆日期'
    },
    cancelText: {// 取消按钮文案
      type: String,
      value: '取消'
    },
    sureText: {// 确定按钮文案
      type: String,
      value: '确定'
    },
  },
 
  /**
   * 组件的初始数据
   */
  data: {
    columnsData: [],
    value: [],
    backData: [],
    height: 0,
    isOpen: false,
    isUseKeywordOfShow: false,
    scrollEnd: true, // 滚动是否结束
    lastValue: [], // 上次各个colum的选择索引
    tempValue: [],
    isFirstOpen: true,
    onlyKey: '',
    defaultPickDataTemp: '',
    listDataTemp: ''
  },
  /**
   * 组件的方法列表
   */
  methods: {
    tapModal() {
      this.properties.isShowPicker = false
      this._closePicker()
    },
    cancle() {
      this.triggerEvent('cancle')
      this._closePicker()
    },
    sure() {
      const { scrollEnd, tempValue } = this.data
      if (!scrollEnd) return
      const backData = this._getBackDataFromValue(tempValue)
      this.setData({
        backData
      })
      this.triggerEvent('sure', {
        choosedData: backData,
        choosedIndexArr: tempValue
      })
      this._closePicker()
    },
    _bindChange(e) {
      const { scrollType } = this.properties
      const { lastValue } = this.data
      let val = e.detail.value
      switch (scrollType) {
        case 'normal':
          this.data.tempValue = val.concat()
          this.data.tempValue = val.concat()
          break
        case 'link':
          // let column_02 = this._getColumnData(this.properties.listData[val[0]].children);
          // let column_03 = this._getColumnData(this.properties.listData[val[0]].children[val[1]].children);
          var tempArray = []
          if (val.length > 1) {
            val.slice(0, val.length - 1).reduce((t, c, i) => {
              const v = t[c].children
              tempArray.push(this._getColumnData(v))
              return v
            }, this.properties.listData)
          }
          // let columnsData = [this.data.columnsData[0],column_02,column_03];
          var columnsData = [this.data.columnsData[0], ...tempArray]
 
          // 设置value关联
          var compareIndex = this._getScrollCompareIndex(lastValue, val)
          if (compareIndex > -1) {
            let tempI = 1
            while (val[compareIndex + tempI] !== undefined) {
              val[compareIndex + tempI] = 0
              tempI++
            }
          }
          val = this._validate(val)
          this.data.lastValue = val.concat()
          this.data.tempValue = val.concat()
          this.setData({
            columnsData
            // value: val
          })
      }
    },
    _validate(val) {
      const { columnsData } = this.data
      columnsData.forEach((v, i) => {
        if (columnsData[i].length - 1 < val[i]) {
          val[i] = columnsData[i].length - 1
        }
      })
      this.setData({
        value: val
      })
      return val
    },
    _bindpickend() {
      this.data.scrollEnd = true
    },
    _bindpickstart() {
      this.data.scrollEnd = false
    },
    _openPicker() {
      if (!this.data.isFirstOpen) {
        if (this.properties.listData.length !== 0) {
          this._setDefault(this._computedBackData(this.data.backData))
        }
      }
      this.data.isFirstOpen = false
      this.setData({
        isOpen: true
      })
    },
    _closePicker() {
      this.setData({
        isOpen: false
      })
    },
    _getColumnData(arr) {
      return arr.map((v) => this._fomateObj(v))
    },
    _fomateObj(o) {
      const tempO = {}
      for (const k in o) {
        k !== 'children' && (tempO[k] = o[k])
      }
      return tempO
    },
    _getScrollCompareIndex(arr1, arr2) {
      let tempIndex = -1
      for (let i = 0, len = arr1.length; i < len; i++) {
        if (arr1[i] !== arr2[i]) {
          tempIndex = i
          break
        }
      }
      return tempIndex
    },
    // 根据id获取索引
    _getIndexByIdOfObject(listData, idArr, key, arr) {
      if (!Array.isArray(listData)) return
      for (let i = 0, len = listData.length; i < len; i++) {
        if (listData[i][key] === idArr[arr.length][key]) {
          arr.push(i)
          return this._getIndexByIdOfObject(listData[i].children, idArr, key, arr)
        }
      }
    },
    _setDefault(inBackData) {
      const { scrollType } = this.properties
      let { listData, defaultPickData } = this.properties
 
      const { lastValue } = this.data
      if (inBackData) {
        defaultPickData = inBackData
      }
      let backData = []
      switch (scrollType) {
        case 'normal':
          if (isPlainObject(listData[0][0])) {
            this.setData({
              isUseKeywordOfShow: true
            })
          }
          if (Array.isArray(defaultPickData) && defaultPickData.length > 0) {
            backData = listData.map((v, i) => v[defaultPickData[i]])
            this.data.tempValue = defaultPickData
            this.data.lastValue = defaultPickData
          } else {
            backData = listData.map((v) => v[0])
          }
          this.setData({
            columnsData: listData,
            backData: backData,
            value: defaultPickData
          })
          break
        case 'link':
          // let column_01 = this._getColumnData(newVal);
          // let column_02 = this._getColumnData(newVal[0].children);
          // let column_03 = this._getColumnData(newVal[0].children[0].children);
          // let columnsData = [column_01,column_02,column_03];
          var columnsData = []
          // 如果默认值
          if (Array.isArray(defaultPickData) && defaultPickData.length > 0 && defaultPickData.every((v, i) => isPlainObject(v))) {
            const key = this.data.onlyKey = Object.keys(defaultPickData[0])[0]
 
            const arr = []
 
            this._getIndexByIdOfObject(listData, defaultPickData, key, arr)
 
            defaultPickData = arr
            let tempI = 0
            do {
              lastValue.push(defaultPickData[tempI])
              columnsData.push(this._getColumnData(listData))
              listData = listData[defaultPickData[tempI]].children
              tempI++
            } while (listData)
            backData = columnsData.map((v, i) => v[defaultPickData[i]])
            // 如果没有默认值
          } else {
            this.data.onlyKey = this.properties.keyWordsOfShow || 'name'
            do {
              lastValue.push(0)
              columnsData.push(this._getColumnData(listData))
              listData = listData[0].children
            } while (listData)
            backData = columnsData.map((v) => v[0])
          }
          this.data.tempValue = defaultPickData
          this.data.lastValue = defaultPickData
          this.setData({
            isUseKeywordOfShow: true,
            columnsData,
            backData
          })
          setTimeout(() => {
            this.setData({
              value: defaultPickData
            })
          }, 0)
          break
      }
    },
    _computedBackData(backData) {
      const { scrollType, listData } = this.properties
      const { onlyKey } = this.data
      if (scrollType === 'normal') {
        return backData.map((v, i) => listData[i].findIndex((vv, ii) => this._compareObj(v, vv)))
      } else {
        const t = backData.map((v, i) => {
          const o = {}
          o[onlyKey] = v[onlyKey]
          return o
        })
 
        return t
      }
    },
    _compareObj(o1, o2) {
      const { keyWordsOfShow } = this.properties
      if (typeof o1 !== 'object') {
        return o1 === o2
      } else {
        return o1[keyWordsOfShow] === o2[keyWordsOfShow]
      }
    },
    _getBackDataFromValue(val) {
      let tempArr = []
      if (val.length > 0) {
        tempArr = this.data.columnsData.reduce((t, v, i) => {
          return t.concat(v[val[i]])
        }, [])
      } else {
        tempArr = this.data.columnsData.map((v, i) => v[0])
      }
      return tempArr
    },
    _compareDate() { // 完全相等返回true
      const { defaultPickDataTemp, listDataTemp } = this.data
      const { defaultPickData, listData } = this.properties
 
      return defaultPickDataTemp === defaultPickData && listDataTemp === listData
    },
    _setTempData() {
      const { defaultPickData, listData } = this.properties
      this.data.defaultPickDataTemp = defaultPickData
      this.data.listDataTemp = listData
    }
  }
})

第五步:创建一个tool.js文件

function _typeof(obj) {
  return Object.prototype.toString.call(obj).slice(8, -1).toLowerCase();
}
function isString(obj) { //是否字符串
  return _typeof(obj) === 'string'
}
function isPlainObject(obj) {
  return _typeof(obj) === 'object';
}
module.exports = {
  isString,
  isPlainObject
}

第六步:在所需的页面的json中进行引用

{
  "usingComponents": {
    "picker": "../../picker/picker"
  }
}

第七步:在所需的页面的wxml中写入布局

 <button bindtap="showPicker_11">时间的五列联动picker</button>
<view>选择数据:{{picker_11_data}}</view>
<view>选择索引:{{picker_11_index}}</view>
<picker isShowPicker="{{isShow_11}}" keyWordsOfShow="name" bindsure="sureCallBack_11" bindcancle="cancleCallBack_11" scrollType="link" listData="{{listData_11}}"></picker>

第八步:在所需的页面的js中调用我们的自定义选择器

// pages/index/index.js
import { times } from './time.js';
Page({
 
  /**
   * 页面的初始数据
   */
  data: {
    isShow_11: false,
    listData_11:times,
    picker_11_data:[],
  },
  onLoad () {
    setTimeout(() => {
      this.setData({
        defaultPickData_08:[
          {code:'110000'},{code:'110100'},{code:'110101'}
        ]
      })
    },3000)
  },
 
  showPicker_11: function () {
    this.setData({
      isShow_11: true,
    })
 
  },
 
  sureCallBack_11 (e) {
    let data = e.detail
    console.log("data",data);
    this.setData({
      isShow_11: false,
      picker_11_data: JSON.stringify(e.detail.choosedData),
      picker_11_index:JSON.stringify(e.detail.choosedIndexArr)
 
    })
  },
  cancleCallBack_11 () {
    this.setData({
      isShow_11: false
    })
  },
 
})

第九步:创建一个time.js的文件

微信小程序自定义日期选择器的示例分析

const times =[ {
  name:'2021年',
  id:1,
  children:[
    {
      name:'1月',
      id:11,
      children:[
        {
          name:'1日',
          id:111,
          children:[
            {
              name:'1时',
              id:1111,
              children:[
                {
                  name:'1分',
                  id:11111,
                },
                {
                  name:'2分',
                  id:11112,
                },
              ]
            },
          ]
        },
        {
          name:'2日',
          id:112,
          children:[
            {
              name:'1时',
              id:1121,
              children:[
                {
                  name:'1分',
                  id:11111,
                },
                {
                  name:'2分',
                  id:11112,
                },
               
              ]
            },
            {
              name:'2时',
              id:1121,
              
            },
          ]
        },
        {
          name:'3日',
          id:113,
          children:[
            {
              name:'小',
              id:1131,
            },
            {
              name:'大',
              id:1132
            },
          ]
        }
      ]
    },
    {
      name:'2月',
      id:12,
      children:[
        {
          name:'1日',
          id:121,
          children:[
            {
              name:'1时',
              id:1121,
              children:[
                {
                  name:'1分',
                  id:11111,
                },
                {
                  name:'2分',
                  id:11112,
                },
               
              ]
            },
            {
              name:'2时',
              id:1121,
              
            },
          ]
        },
        {
          name:'2日',
          id:122,
          children:[
            {
              name:'1时',
              id:1121,
              children:[
                {
                  name:'1分',
                  id:11111,
                },
                {
                  name:'2分',
                  id:11112,
                },
               
              ]
            },
            {
              name:'2时',
              id:1121,
              
            },
          ]
        },
        {
          name:'3日',
          id:123,
          children:[
            {
              name:'1时',
              id:1121,
              children:[
                {
                  name:'1分',
                  id:11111,
                },
                {
                  name:'2分',
                  id:11112,
                },
               
              ]
            },
            {
              name:'2时',
              id:1121,
              
            },
          ]
        }
      ]
    }
  ]
},
{
  name:'2022年',
  id:1,
  children:[
    {
      name:'1月',
      id:11,
      children:[
        {
          name:'1日',
          id:111,
          children:[
            {
              name:'1时',
              id:1111,
              children:[
                {
                  name:'1分',
                  id:11111,
                },
                {
                  name:'2分',
                  id:11112,
                },
              ]
            },
          ]
        },
        {
          name:'2日',
          id:112,
          children:[
            {
              name:'1时',
              id:1121,
              children:[
                {
                  name:'1分',
                  id:11111,
                },
                {
                  name:'2分',
                  id:11112,
                },
               
              ]
            },
            {
              name:'2时',
              id:1121,
              
            },
          ]
        },
        {
          name:'3日',
          id:113,
          children:[
            {
              name:'小',
              id:1131,
            },
            {
              name:'大',
              id:1132
            },
          ]
        }
      ]
    },
    {
      name:'2月',
      id:12,
      children:[
        {
          name:'1日',
          id:121,
          children:[
            {
              name:'1时',
              id:1121,
              children:[
                {
                  name:'1分',
                  id:11111,
                },
                {
                  name:'2分',
                  id:11112,
                },
               
              ]
            },
            {
              name:'2时',
              id:1121,
              
            },
          ]
        },
        {
          name:'2日',
          id:122,
          children:[
            {
              name:'1时',
              id:1121,
              children:[
                {
                  name:'1分',
                  id:11111,
                },
                {
                  name:'2分',
                  id:11112,
                },
               
              ]
            },
            {
              name:'2时',
              id:1121,
              
            },
          ]
        },
        {
          name:'3日',
          id:123,
          children:[
            {
              name:'1时',
              id:1121,
              children:[
                {
                  name:'1分',
                  id:11111,
                },
                {
                  name:'2分',
                  id:11112,
                },
               
              ]
            },
            {
              name:'2时',
              id:1121,
              
            },
          ]
        }
      ]
    }
  ]
},]
module.exports = {
  times,
}

完成上述步骤后,一个自定义的日期选择器就完成了

微信小程序自定义日期选择器的示例分析

上述就是小编为大家分享的微信小程序自定义日期选择器的示例分析了,如果刚好有类似的疑惑,不妨参照上述分析进行理解。如果想知道更多相关知识,欢迎关注亿速云行业资讯频道。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI