微信小程序自定义yPicker组件实现省市区三级联动
自从上一篇文章 出来以后,有人私聊我说能不能从头分析一下我开源的自定义组件?一直没时间。这不,最近项目中有个需求是 省市区三级联动 ,我就顺便从组件库中的第一个 「)」组件开始说一下这两个功能的实现。
简单说一下“自定义日期-时间组件”
它的背景是项目的第一版当时发现微信小程序内置的日期组件picker只能精确到某一天(年月日),我们很多时候需要年月日时分甚至是年月日时分秒(如结束时间/发布时间)。
笔者仔细翻阅了官方文档和许多博主文章发现提出了各种各样的解决方案(但很遗憾没发现有博主详细公开代码),对于这样一个其实并不需要“联动”、列数也不固定的功能,用多列picker模拟多列选择器 即可。
<picker mode="multiSelector" bindchange="bindMultiPickerChange" bindcolumnchange="bindMultiPickerColumnChange" value="{{multiIndex}}" range="{{multiArray}}"> <input value='{{time}}' readonly="" disabled="true" placeholder='{{defaulttext}}' /> </picker>
其中 readonly="" disabled="true"
的作用是使“input聚焦时软键盘不弹出”(两个属性作用一样,都写是因为Android和iOS的兼容性问题)。
用input代替view是因为input的placeholder方便实现“无选中时默认提示”的效果。
主要实现策略
如上所示,监听了两个事件,分别是日期选择窗口弹出时以及点击“确定”按钮时触发函数change、多列选择器中每一列滑动时触发事件columnchange。
- change中很简单只需要把选中的数据暴露给页面中(或者通过
triggerEvent
返回给调用页面)即可; - columnchange中要做的就是当前选中的每一列的值填充到data中对应数组的某一项。比如
e.detail.column==1
时表示当前滑动的是第二列(月份),此时需要判断的是每一月有几天
if (e.detail.column == 1) { let num = parseInt(this.data.multiArray[e.detail.column][e.detail.value]); let temp = []; if (num == 1 || num == 3 || num == 5 || num == 7 || num == 8 || num == 10 || num == 12) { //判断31天的月份 for (let i = 1; i <= 31; i++) { if (i < 10) { i = "0" + i; } temp.push("" + i); } this.setData({ ['multiArray[2]']: temp //第三列天数更新(根据月份) }); } }
注意 多列picker组件监听两个参数multiArray和multiIndex,他们都是数组!
multiArray主要用来表示监听几列,其元素都是一个个数组,如[years, months, days, hours, minutes]
multiIndex是当前每一列(点开时的)初始值!如[10, meng_date.getMonth(), meng_date.getDate()-1, meng_date.getHours(), meng_date.getMinutes()]
,multiIndex中的值也被用来当做取multiArray中元素时的第二个索引!
说说省市区三级联动实现
先将城市列表文件发出来(永久免费下载)
提取码: wc3g
使用时按如下引入即可(是一个citysearch.js文件)
import placeArrays from 'citysearch文件路径'; const placeArray=placeArrays.placeArray
正式开始
不知大家有没有使用过,或听过小程序的 picker-view
组件,其定位就是嵌入页面的滚动选择器。
它有三个参数
参数 | 类型 | 说明 |
---|---|---|
value | Number Array | 数组中的数字依次表示 picker-view 内的 picker-view-colume 选择的第几项(下标从 0 开始),数字大于 picker-view-column 可选项长度时,选择一项。 |
indicator-style | String | 设置选择器中间选中框的样式 |
bindchange | EventHandle | 当滚动选择,value 改变时触发 change 事件,event.detail = {value: value} value为数组,表示 picker-view 内的 picker-view-column 当前选择的是第几项(下标从 0 开始) |
需要注意的是其中只可放置<picker-view-column/>
组件,其他节点不会显示,其孩子节点的高度会自动设置成与picker-view的选中框的高度一致。
有了这个组件,我们是不是能想到在一个弹出view中设置三个picker-view组件,每个组件中放一个picker-view-column组件用于展示当前列?
value中也可以只放一个number(通常可以放数组元素下标),picker-view会自动将其转为
[下标值]
就像这样
<view style="width:100%;position:fixed;bottom:0;left:0;z-index:10000;height:500rpx;background-color:white"> <!-- 仿原生picker的“确定”和“取消”按钮 --> <view style="display:flex;width:100%;height:100%"> <view style="position: absolute;:0;width:100%;height:100rpx;z-index:1000000;display:flex;justify-content:space-between;align-items:center;"> <view style="width:calc(100% / 3);text-align:center;color:rgba(0,0,0,.6);font-size:39rpx" bindtap="displayer">取消 </view> <view style="width:calc(100% / 3);text-align:center;color:rgb(63,142,255);font-size:39rpx" bindtap="confirm">确定 </view> </view> <picker-view indicator-style="height: 200rpx;" style="width: 100%;height: 300rpx;text-align: center;margin-:150rpx" value="{{pIndex}}" bindchange="changeProvince"> <picker-view-column> <view wx:for="{{placeArray}}" wx:key="name" style="line-height: 77rpx">{{item.name}}</view> </picker-view-column> </picker-view> <picker-view indicator-style="height: 200rpx;" style="width: 100%;height: 300rpx;text-align: center;margin-:150rpx" value="{{cIndex}}" bindchange="changeCity"> <picker-view-column> <view wx:for="{{placeArray[pIndex].city}}" wx:key="name" style="line-height: 77rpx">{{item.name}}</view> </picker-view-column> </picker-view> <picker-view indicator-style="height: 200rpx;" style="width: 100%;height: 300rpx;text-align: center;margin-:150rpx" value="{{aIndex}}" bindchange="changeArea"> <picker-view-column> <view wx:for="{{placeArray[pIndex].city[cIndex].area}}" wx:key="this" style="line-height: 77rpx">{{item}} </view> </picker-view-column> </picker-view> </view> </view>
可以看到,每一个picker-view-column中做的唯一一件事就是遍历固定的某一列(某一个数组)并渲染出来。
然后如
// js-data data:{ placeArray: placeArray, province: "",//placeArray[0].name - 省 pIndex: 0, city: "",//placeArray[0].city[0].name - 市 cIndex: 0, area: "",//placeArray[0].city[0].area[0] - 区 aIndex: 0, }
上wxml中为每一列(picker-view)都绑定了一个change函数——滑动时触发
changeProvince: function(e){ const val = e.detail.value this.setData({ pIndex: val, cIndex: 0, aIndex: 0, province: placeArray[val].name, city: placeArray[val].city[0].name, area: placeArray[val].city[0].area[0] }) }, changeCity: function(e){ const val = e.detail.value this.setData({ cIndex: val, aIndex: 0, city: placeArray[this.data.pIndex].city[val].name, area: placeArray[this.data.pIndex].city[val].area[0] }) }, changeArea: function(e){ const val = e.detail.value this.setData({ aIndex: val, area: placeArray[this.data.pIndex].city[this.data.cIndex].area[val] }) },
他们的作用就是把当前选择列的选中元素(出现在indicator-style视野中的元素)暴露到页面上,并将下标定位到这里 —— 以便在页面无刷新下的下一次点开时从这里开始找!
然后最重要的一点就是在滑动停止时,将两列的数据重新定位到第一个!
——,你也可以选择在一个picker-view中放置多个picker-view-column组件,这样的话就和上面多列picker一样,需要多个数组联动来传递数据了!
到此这篇关于微信小程序自定义yPicker组件实现省市区三级联动功能的文章就介绍到这了,更多相关微信小程序自定义yPicker组件内容请搜索狼蚁SEO以前的文章或继续浏览狼蚁网站SEO优化的相关文章希望大家以后多多支持狼蚁SEO!
编程语言
- 如何快速学会编程 如何快速学会ug编程
- 免费学编程的app 推荐12个免费学编程的好网站
- 电脑怎么编程:电脑怎么编程网咯游戏菜单图标
- 如何写代码新手教学 如何写代码新手教学手机
- 基础编程入门教程视频 基础编程入门教程视频华
- 编程演示:编程演示浦丰投针过程
- 乐高编程加盟 乐高积木编程加盟
- 跟我学plc编程 plc编程自学入门视频教程
- ug编程成航林总 ug编程实战视频
- 孩子学编程的好处和坏处
- 初学者学编程该从哪里开始 新手学编程从哪里入
- 慢走丝编程 慢走丝编程难学吗
- 国内十强少儿编程机构 中国少儿编程机构十强有
- 成人计算机速成培训班 成人计算机速成培训班办
- 孩子学编程网上课程哪家好 儿童学编程比较好的
- 代码编程教学入门软件 代码编程教程