微信小程序有默认省市区三级联动组件
<view class="section">
<view class="section__title">省市区选择器</view>
<picker mode="region" bindchange="bindRegionChange" value="{{region}}" custom-item="{{customItem}}">
<view class="picker">
当前选择:{{region[0]}},{{region[1]}},{{region[2]}}
</view>
</picker>
</view>
bindRegionChange: function (e) {
console.log('picker发送选择改变,携带值为', e.detail.value)
this.setData({
region: e.detail.value
})
}
这样可以满足基本的开发需求,但是有时候后台要传省市区的id,这时候这个组件不满足这个需求了。
在data里面定义几个值
region: ['浙江省', '杭州市', '西湖区'],
regionArray: [[], [], []],
regionOpts: [[], [], []],
regionIndex: [0, 0, 0],
prevRegionArray: null,
prevRegionOpts: null,
prevRegionIndex: null,
在onload里面
onLoad: function (option) {
let getCallBack = (_regionIndex, initRegionId) => {
return (opts, array) => {
for (let index in opts) {
let opt = opts[index];
if (opt.region_id == initRegionId) {
let regionIndex = this.data.regionIndex;
regionIndex[_regionIndex] = index;
this.setData({ regionIndex });
}
}
this.changeRegionOpt(_regionIndex, opts, array);
}
};
this.getRegionOpts(1, getCallBack(0, 2));
2 && this.getRegionOpts(2, getCallBack(1, 52));
52 && this.getRegionOpts(52, getCallBack(2, 500));
},
从后台获取省市区三级联动
bindRegionChange: function (e) {
console.log('picker发送选择改变,携带值为', e.detail.value)
this.setData({
region: e.detail.value
})
},
/*省市区联动*/
getRegionOpts(regionId, callBack) {
Trequest({
url: "region/children",
method: 'post',
data: {
m: 'area',
a: 'get_area',
parent_id: regionId
},
callback({ data: r }) {
if (!Array.isArray(r))
return;
var opts = [];
var regionArray = [];
r.forEach(({ region_id, region_name }, index) => {
opts.push({ region_id, region_name });
regionArray.push(region_name);
});
callBack(opts, regionArray);
}
})
},
changeRegionOpt(index, regionOpts, regionArray) {
let { regionArray: mArray, regionOpts: mOpts } = this.data;
mArray[index] = regionArray;
mOpts[index] = regionOpts;
this.setData({
regionArray: mArray,
regionOpts: mOpts
});
},
regionFocus() {
let {
regionArray, regionOpts, regionIndex
} = this.data;
this.setData({
prevRegionArray: JSON.parse(JSON.stringify(regionArray)),
prevRegionOpts: JSON.parse(JSON.stringify(regionOpts)),
prevRegionIndex: JSON.parse(JSON.stringify(regionIndex))
});
},
regionCancel() {
let {
prevRegionArray, prevRegionOpts, prevRegionIndex
} = this.data;
this.setData({
regionArray: prevRegionArray,
regionOpts: prevRegionOpts,
regionIndex: prevRegionIndex
});
},
regionPickerChange({ detail: { value: regionIndex } }) {
let opts = this.data.regionOpts;
let userInfo = this.data.userInfo;
/*获取对应的省市区*/
userInfo.province = (opts[0][regionIndex[0]] || {}).region_id;
userInfo.city = (opts[1][regionIndex[1]] || {}).region_id;
userInfo.district = (opts[2][regionIndex[2]] || {}).region_id;
/*保存到用户信息*/
this.setData({ userInfo, regionIndex });
},
regionPickerColumnChange({ detail: { value: index, column: col } }) {
let region = this.data.regionOpts[col][index];
/*如果改变了省或者市,则获取对应的市或区的子集*/
if (col === 0)
/*获取市列表*/
this.getRegionOpts(region.region_id, (opts, array) => {
/*更新市列表*/
this.changeRegionOpt(1, opts, array);
/*获取第一个市对应的区列表并更新*/
this.getRegionOpts(opts[0].region_id, this.changeRegionOpt.bind(this, 2))
}
);
else if (col === 1)
/*获取区列表并更新*/
this.getRegionOpts(region.region_id, this.changeRegionOpt.bind(this, 2))
},
在wxml里面
<view class='line_item item_one senderStaticDiv flex_bt' bindtap='accountSet'>
<text class='_left'>所在省市区</text>
<view class='_right _right_rt '>
<picker mode="multiSelector" bindtap="regionFocus"
bindcancel = 'regionCancel'
bindchange="regionPickerChange" bindcolumnchange="regionPickerColumnChange" value="{{regionIndex}}" range="{{regionArray}}">
<view class="picker">
{{regionArray[0][regionIndex[0]]}}
{{regionArray[1][regionIndex[1]]}}
{{regionArray[2][regionIndex[2]]}}
</view>
</picker>
</view>
</view>