微信小程序使用Vant Weapp(1.10.10版本)van-cascader组件实现省市区懒加载选择
效果图如下:
wxml代码:
<view class="container">
<van-field value="{{ fieldValue }}" is-link readonly label="地区" placeholder="请选择所在地区" bind:tap="onClick" />
<van-popup show="{{ show }}" round position="bottom">
<van-cascader id="my-cascader" title="请选择所在地区" options="{{options}}" value="{{ cascaderValue }}"
bind:close="onClose" bind:finish="onFinish" active-color="#ee0a24" bind:change="handleChange" />
</van-popup>
</view>
js代码:
const { http } = getApp();
import { getAreaUrl } from '../../api/index'; //接口
Page({
/**
* 页面的初始数据
*/
data: {
show: false,
options: [
// 省市区数据
],
fieldValue: '',
cascaderValue: '',
level: 3 //选择到第几层
},
//完成时触发
onFinish(e) {
const { selectedOptions, value } = e.detail;
const fieldValue = selectedOptions.map((option) => option.text).join('>');
this.setData({
fieldValue,
cascaderValue: value,
show: false
});
},
onClick() {
this.setData({
show: true
});
},
onClose() {
this.setData({
show: false
});
},
handleChange(event) {
let { level } = this.data;
// 获取选中的值
const { value, tabIndex } = event.detail;
// 获取当前选中的对象
const selectedOption = this.getSelectedOption(value);
console.log(selectedOption);
//判断台湾省的选中
if (selectedOption.text == '台湾省' && tabIndex == 0) {
this.getArea(0);
return;
}
// 判断是否选择三级省市区的判断
if (selectedOption.level == level) {
return;
}
// 判断是否有子级数据
if (!selectedOption.children || !selectedOption.children.length) {
http.get(getAreaUrl + `/${value}`).then(({ data = {} }) => {
// 更新当前选中对象的 children 属性和 value 值
const arr = data.map((p) => ({
text: p.areaName + '',
value: p.areaCode + '',
level: p.level,
children: p.level == level ? undefined : [] //判断只渲染三级
}));
//赋值子集
selectedOption.children = arr;
selectedOption.value = value;
this.setData({
options: this.data.options,
cascaderValue: value // 更新组件状态(重要)
});
});
} else {
// 更新 cascaderValue 值 更新组件状态
this.setData({
cascaderValue: value
});
}
},
// 根据 value 返回匹配的选项对象 value:当前点击的code
getSelectedOption(value) {
const options = this.data.options;
//递归遍历循环
let matchedOption;
const addTree = (option) => {
if (option.value === value) {
matchedOption = option;
}
if (!matchedOption && option.children) {
option.children.forEach((child) => addTree(child));
}
};
//找对对应children
options.forEach((option) => addTree(option));
return matchedOption;
},
// 加载省份数据
getArea(parentId) {
http.get(getAreaUrl + `/${parentId}`).then(({ data = {} }) => {
const provinces = data.map((p) => ({
text: p.areaName + '',
value: p.areaCode + '',
level: p.level,
children: p.areaCode != '710000' ? [] : undefined // 城市列表先占位,后续再加载 台湾省除外
}));
this.setData({ options: provinces });
});
},
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
this.getArea(0);
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady() {},
/**
* 生命周期函数--监听页面显示
*/
onShow() {},
/**
* 生命周期函数--监听页面隐藏
*/
onHide() {},
/**
* 生命周期函数--监听页面卸载
*/
onUnload() {},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh() {},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom() {},
/**
* 用户点击右上角分享
*/
onShareAppMessage() {}
});