当前位置:网站首页>微信小程序自定义日期选择器(带标题的)
微信小程序自定义日期选择器(带标题的)
2022-08-09 14:55:00 【写的都是BUG】
日期选择器是我们在写项目的过程中经常遇到的,有需要标题的选择器,也有不需要标题的选择器
今天给大家带来一个自定义的时间选择器,废话不多说,直接上代码
第一步:先创建一个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 style="font-weight: bold;">{
{titleText}}</text>
<view bindtap="sure">
<text style="color:aqua;">{
{sureText}}</text>
</view>
</view>
<picker-view
value="{
{value}}"
class="picker-content"
bindpickstart="_bindpickstart"
bindchange="_bindChange"
bindpickend="_bindpickend"
indicator-style="{
{indicatorStyle}}"
mask-style="{
{maskStyle}}"
>
<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,
}完成上述步骤后,一个自定义的日期选择器就完成了

欢迎大家提问和指点
边栏推荐
猜你喜欢
随机推荐
Matlab修改Consolas字体
CV复习:BatchNorm
如何防止浏览器指纹关联
一些需要思考的物理问题
6大论坛,30+技术干货议题,2022首届阿里巴巴开源开放周来了!
What is an index in MySql?What kinds of indexes are commonly used?When does an index fail?
文件操作的实例——下载并合并流式视频文件
Seize the opportunity of quantitative trading fund products, and quantitative investment has room for development?
浏览器中的302你真的知道吗
NetCore 5.0连接MySql
Qt对话框中show和exec的区别
大数组减小数组常用方法
相干光(光学)
What do professional quantitative traders think about quantitative trading?
如何在实际操作中进行亚马逊测评
Analysis: Which method is used to build a stock quantitative trading database?
几何光学简介
.Net Core 技巧小结
如何选择可靠的亚马逊代运营
How to achieve stable profit through the stock quantitative trading interface?








