微信小程序虽然已经有现成的封装好的省市区选择器给开发者使用,然鹅不幸的是,微信地址库的数据和公司用的地址库数据很难一一对上,那就只能撸起袖子自己写个组件了。
最终效果
思维导图
主要代码
组件 region-picker.js
/* region-picker.js */
import area from '本地 json 数据';
Component({
properties: {
showRegion: {
type: Boolean,observer: function(newVal,oldVal) {
this.setData({
dialog: newVal,});
},},regionValue: {
type: Array,value: [],51); font-weight: 700;">if (newVal.length > 0) {
let select = -1;
for (let i = newVal.length - 1; i >= 0; i--) {
if (newVal[i].id !== '') {
select = i;
break;
}
}
// 除最低级别区(select = 2)以外,需要获取当前级别下一级的数据
this.setData({
['region.tabs']: newVal,['region.select']: select < 2 ? select+1 : select,() => {
this.setData({
area: this.getChildArea(select < 1 : select),});
});
}
},data: {
dialog: false,area: area,region: {
tabs: [
{
name: '请选择',id: '',{
name: 0,methods: {
// 关闭 picker 触发的方法
emitHideRegion: function() {
if (this.data.region.tabs[2].id === '') {
wx.showToast({
title: '请选择所在地',icon: 'none',duration: 2000,});
return false;
}
let myEventDetail = {}; // detail对象,提供给事件监听函数
let myEventOption = {}; // 触发事件的选项
this.setData({
dialog: !data.dialog,});
myEventDetail = {
showRegion: data.region.tabs,};
this.triggerEvent('myevent',myEventDetail,myEventOption);
},bindRegionChange: function(e) {
// 获取当前选中项的name和id并赋值给data中的数据
let id ='region.tabs[' + data.region.select + '].id';
let name ='].name';
this.setData({
[id]: e.target.dataset.id,[name]: e.target.dataset.name,});
// 除了三级以外的需要获取对应子选项
data.region.select < 2) {
this.setData({
['region.select']: ++data.region.select,() => {
// 获取子选项
this.setData({
area: this.getChildArea(data.region.select),});
});
} else {
// 三级选项选择完毕关闭省市区选择器
this.emitHideRegion();
}
},getChildArea: function(level) {
let _id = '';
// 默认取完整的数据
let _area = area;
// 根据层级取当前层级下的数据
for (let i = 0; i < level; i++) {
_id = 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) false;
// 当前选中tab和级别小于当前选中tab的状态都置为初始化状态
for (let i = level; i < 3; i++) {
let string = 'region.tabs['+ i +']';
this.setData({
[string]: {
name: 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' : ''}}">
<"free-dialog__mask" bindtap="emitHideRegion"></view>
<"free-dialog__container">
<"free-dialog__container__header">
<view>选择所在地区</view>
<image
src="自行替换36rpx*36rpx的x图标"
class="close"
bindtap="emitHideRegion">
</image>
</view>
<"free-dialog__container__content">
<"free-content {{isIphoneX ? 'ipx' : ''}}">
<"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=}"
bindtap="changeRegionLevel">
{{item.name}}
</view>
</view>
<scroll-view scroll-y class="free-content__scroll">
<"free-content__scroll__item"
wx:for={{area}"id"
data-id={{item.id}}"
data-name={{item.name}"bindRegionChange">
@H_46_404@scroll-view>
</view>
</view>
</view>
</view>
复制代码
组件 region-picker.wxss
页面的 WXML
/* 页面的 WXML */
<view bindtap="chooseRegion">请选择</view>
<text wx:if={{regionValue[0].id}}">{{regionValue[0].name}}</text>
<{{regionValue[1].id}{{regionValue[1].name}}</{{regionValue[2].id}{{regionValue[2].name}}</text>
</view>
...
<region-picker
region-value={{regionValue}}"
show-region={{showRegion}}"
bind:myevent="emitHideRegion">
</region-picker>
复制代码
页面的 js
总结
需要注意下的是,最低级别区级别是个特殊的临界点,因为区后面没有更低级别,所以不需要获取下一级别的数据,也不能触发 tab 事件。
然后父组件传递子自组件的值,如果后期父组件变更了这个值,子组件可以在响应函数 observer 里监听到值的变化。
我本次使用的本地省市区 JSON 数据格式为:
/* area.js */
module.exports = [{
id: '...',name: '...'
},...]
},...]
},...]
复制代码
写的不是特别好,也希望能帮助到有需要的人吧,有疑问戳微信小程序官方文档,没有什么比官方文档更靠谱的了!
原文:https://juejin.im/post/5b7520966fb9a0099744a96f
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。