撸个微信小程序的省市区选择器
微信小程序虽然已经有现成的封装好的省市区选择器给开发者使用,然鹅不幸的是,微信地址库的数据和公司用的地址库数据很难一一对上,那就只能撸起袖子自己写个组件了。
最终效果
思维导图
主要代码
组件区域选择器。射流研究…
/*区域选取器。js */导入区域自'本地json数据;组件({ properties : { show region : { type : Boolean,observer: function(newVal,oldVal)} this。setdata({ dialog :NewVal });},},regionvalue : { type : Array,value: [],observer:函数(newVal,oldVal){ if(NewVal。长度0){ let select=-1;用于(让I=NewVal。长度-1;I=0;i - ) { if (newVal[i]).身份证!==' '){ select=I;打破;} } //除最低级别区(选择=2)以外,需要获取当前级别下一级的数据这个。setdata({[' region。tab ']: NewVal,['region.select']: select 2?选择1 : select,},()={ this。setdata({ area : this。getchildarea(选择2?选择1 : select),});});} },},},data: { dialog: false,area: area,region : { tab 3360 [{ name : '请选择,id: ' ',},{ name: '请选择,id: ' ',},{ name: '请选择,id: ' ',},],select: 0,},},methods: { //关闭采摘者触发的方法emitHideRegion:函数(){ if(this。数据。地区。选项卡[2].id===' '){ wx。ShowToast({ title : }请选择所在地,icon: 'none ',duration: 2000,});返回false}让myEventDetail={ };//详细信息对象,提供给事件监听函数让myEventOption={ };//触发事件的选项this.setData({ dialog:this.data.dialog,});myEventDetail={ show region : this。数据。对话,
regionValue: this.data.region.tabs, }; this.triggerEvent('myevent', myEventDetail, myEventOption); }, bindRegionChange: function(e) { // 获取当前选中项的name和id并赋值给data中的数据 let id ='region.tabs[' + this.data.region.select + '].id'; let name ='region.tabs[' + this.data.region.select + '].name'; this.setData({ [id]: e.target.dataset.id, [name]: e.target.dataset.name, }); // 除了三级以外的需要获取对应子选项 if (this.data.region.select < 2) { this.setData({ ['region.select']: ++this.data.region.select, }, () => { // 获取子选项 this.setData({ area: this.getChildArea(this.data.region.select), }); }); } else { // 三级选项选择完毕关闭省市区选择器 this.emitHideRegion(); } }, getChildArea: function(level) { let _id = ''; // 默认取完整的数据 let _area = area; // 根据层级取当前层级下的数据 for (let i = 0; i < level; i++) { _id = this.data.region.tabs[i].id; for (let j = 0; j < _area.length; j++) { if (_area[j].id === _id) { _area = _area[j]._child; break; } } } return _area; }, // 省市区tab切换 changeRegionLevel: function(e) { let level = e.target.dataset.level; // 三级选项的tab点击无效果 if (level === 2) return false; // 当前选中tab和级别小于当前选中tab的状态都置为初始化状态 for (let i = level; i < 3; i++) { let string = 'region.tabs['+ i +']'; this.setData({ [string]: { name: '请选择', id: '', }, }); } this.setData({ ['region.select']: level, }); this.setData({ area: this.getChildArea(level), }); }, },});复制代码组件 region-picker.wxml
/* region-picker.wxml */<view class="free-dialog {{dialog ? 'free-dialog--show' : ''}}"> <view class="free-dialog__mask" bindtap="emitHideRegion"></view> <view class="free-dialog__container"> <view class="free-dialog__container__header"> <view>选择所在地区</view> <image src="自行替换36rpx*36rpx的x图标" class="close" bindtap="emitHideRegion"> </image> </view> <view class="free-dialog__container__content"> <view class="free-content {{isIphoneX ? 'ipx' : ''}}"> <view class="free-content__tabs"> <view class="free-content__tabs__tab {{region.select === index ? 'select' : ''}}" wx:for="{{region.tabs}}" wx:key="{{index}}" wx:if="{{index <= region.select}}" data-level="{{index}}" bindtap="changeRegionLevel"> {{item.name}} </view> </view> <scroll-view scroll-y class="free-content__scroll"> <view class="free-content__scroll__item" wx:for="{{area}}" wx:key="id" data-id="{{item.id}}" data-name="{{item.name}}" bindtap="bindRegionChange"> {{item.name}} </view> </scroll-view> </view> </view> </view></view>复制代码
组件 region-picker.wxss
/* region-picker.wxss */.free-dialog__mask { position: fixed; top: 0; left: 0; right: 0; bottom: 0; z-index: 10; background: rgba(0, 0, 0, 0.7); display: none;}.free-dialog__container { position: fixed; left: 0; bottom: 0; width: 100%; background: #F1F1F1; transform: translateY(150%); transition: all 0.4s ease; z-index: 11;}.free-dialog--show .free-dialog__container { transform: translateY(0);}.free-dialog--show .free-dialog__mask { display: block;}.free-dialog__container__header { padding: 24rpx 30rpx; text-align: center; background: white;}.free-dialog__container__header .close { position:absolute; right:30rpx; top:31rpx; width:36rpx; height:36rpx;}.free-content { background: white; border-bottom: 40rpx solid white;}.free-content.ipx { border-bottom: 72rpx solid white;}.free-content__tabs__tab { display: inline-block; padding: 12rpx 46rpx; font-size: 32rpx; color: #333; border-bottom: 4rpx solid white;}.free-content__tabs__tab.select { border-color: #FA263C;}.free-content__scroll { padding: 0 40rpx; height: 480rpx; box-sizing: border-box;}.free-content__scroll__item { margin-top: 40rpx; height: 40rpx; line-height: 40rpx; font-size: 28rpx; color: #333;}复制代码
页面的 WXML
/* 页面的 WXML */<view bindtap="chooseRegion">请选择</view><view> <text wx:if="{{regionValue[0].id}}">{{regionValue[0].name}}</text> <text wx:if="{{regionValue[1].id}}">{{regionValue[1].name}}</text> <text wx:if="{{regionValue[2].id}}">{{regionValue[2].name}}</text></view>...<region-picker region-value="{{regionValue}}" show-region="{{showRegion}}" bind:myevent="emitHideRegion"></region-picker>复制代码
页面的 js
/* 页面的 js */Page({ data: { regionValue: [], showRegion: false, }, chooseRegion: function() { this.setData({ showRegion: true, }); }, emitHideRegion: function(e) { this.setData({ showRegion: e.detail.showRegion, regionValue: e.detail.regionValue, }); },});复制代码
总结
需要注意下的是,最低级别区级别是个特殊的临界点,因为区后面没有更低级别,所以不需要获取下一级别的数据,也不能触发 tab 事件。
然后父组件传递子自组件的值,如果后期父组件变更了这个值,子组件可以在响应函数 observer 里监听到值的变化。
我本次使用的本地省市区 JSON 数据格式为:
/* area.js */module.exports = [{ id: '...', name: '...', _child: [{ id: '...', name: '...', _child: [{ id: '...', name: '...' }, ...] }, ...]}, ...]复制代码
写的不是特别好,也希望能帮助到有需要的人吧,有疑问戳微信小程序官方文档,没有什么比官方文档更靠谱的了!
版权声明:撸个微信小程序的省市区选择器是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。