微信小程序自定义数据实现级联省市区组件功能
温馨提示:
本文最后更新于 2025年07月16日,已超过 58 天没有更新。若文章内的图片失效(无法正常加载),请留言反馈或直接联系我。
在微信小程序中,省市区三级联动是常见的功能需求。一种轻量、高效且不依赖第三方组件的实现方式是使用自定义组件和本地 JSON 数据来驱动联动逻辑。本文将从数据准备、组件设计、逻辑处理三方面全面讲解如何实现该功能。
效果图
✨ 一、准备数据源
我们用一份结构清晰的 JSON 文件来定义所有省、市、区信息,例如 regions.json
:
[
{ "id": "11", "name": "北京市", "parent": "0" },
{ "id": "1101", "name": "北京市市辖区", "parent": "11" },
{ "id": "110101", "name": "东城区", "parent": "1101" },
// ...
{ "id": "31", "name": "上海市", "parent": "0" },
{ "id": "3101", "name": "上海市市辖区", "parent": "31" },
{ "id": "310101", "name": "黄浦区", "parent": "3101" }
]
`
id
:每一条的唯一编码name
:显示名称parent
:关联层级,上级编码为0
表示顶级省份
保存到项目 data/regions.json
中,便于后续调用。
🛠 二、自定义组件设计
在 components/area-picker/
下创建 area-picker
组件,包含:
area-picker.json
:{ "component": true }
area-picker.wxml
:<!-- 三列 Picker 用于省市区选择 --> <view class="area-picker"> <picker mode="selector" range="{{provinceList}}" value="{{provinceIndex}}" bindchange="onProvinceChange"> <view>{{provinceList[provinceIndex]}}</view> </picker> <picker mode="selector" range="{{cityList}}" value="{{cityIndex}}" bindchange="onCityChange"> <view>{{cityList[cityIndex]}}</view> </picker> <picker mode="selector" range="{{districtList}}" value="{{districtIndex}}" bindchange="onDistrictChange"> <view>{{districtList[districtIndex]}}</view> </picker> </view>
area-picker.wxss
:.area-picker { display: flex; justify-content: space-between; } picker { flex: 1; margin: 0 5px; }
area-picker.js
:import regions from '../../data/regions.json'; Component({ properties: { value: { type: Object, value: { provinceId: '', cityId: '', districtId: '' } } }, data: { provinceList: [], cityList: [], districtList: [], provinceIndex: 0, cityIndex: 0, districtIndex: 0 }, lifetimes: { attached() { this.initData(); } }, methods: { initData() { const provinces = regions.filter(r => r.parent === '0'); const provinceList = provinces.map(r => r.name); this.setData({ regionData: regions, provinceList }); this.updateCities(0); }, updateCities(provIdx) { const provinces = this.data.regionData.filter(r => r.parent === '0'); const seleProv = provinces[provIdx]; const cities = this.data.regionData.filter(r => r.parent === seleProv.id); const cityList = cities.map(r => r.name); this.setData({ cityList, cityIndex: 0 }); this.updateDistricts(cities, 0); }, updateDistricts(cities, cityIdx) { if (!cities.length) return this.setData({ districtList: [] }); const seleCity = cities[cityIdx]; const districts = this.data.regionData.filter(r => r.parent === seleCity.id); const districtList = districts.map(r => r.name); this.setData({ districtList, districtIndex: 0 }); }, onProvinceChange(e) { const index = e.detail.value; this.setData({ provinceIndex: index }); this.updateCities(index); this.triggerPick(); }, onCityChange(e) { const index = e.detail.value; const provs = this.data.regionData.filter(r => r.parent === '0'); const selProv = provs[this.data.provinceIndex]; const cities = this.data.regionData.filter(r => r.parent === selProv.id); this.setData({ cityIndex: index }); this.updateDistricts(cities, index); this.triggerPick(); }, onDistrictChange(e) { const index = e.detail.value; this.setData({ districtIndex: index }); this.triggerPick(); }, triggerPick() { const provs = this.data.regionData.filter(r => r.parent === '0'); const selProv = provs[this.data.provinceIndex]; const cities = this.data.regionData.filter(r => r.parent === selProv.id); const selCity = cities[this.data.cityIndex]; const districts = this.data.regionData.filter(r => r.parent === selCity.id); const selDistrict = districts[this.data.districtIndex] || {}; this.triggerEvent('change', { provinceId: selProv.id, provinceName: selProv.name, cityId: selCity.id, cityName: selCity.name, districtId: selDistrict.id || '', districtName: selDistrict.name || '' }); } } });
💡 三、实际页面中的调用示例
在页面 pages/index/index.wxml
调用组件:
<area-picker value="{{selectedArea}}" bindchange="onAreaChange" />
<text>当前选择:{{selectedArea.provinceName}} - {{selectedArea.cityName}} - {{selectedArea.districtName}}</text>
在 index.js
中:
Page({
data: {
selectedArea: {
provinceId: '', cityId: '', districtId: '',
provinceName: '', cityName: '', districtName: ''
}
},
onAreaChange(e) {
this.setData({ selectedArea: e.detail });
}
});
效果图
✅ 小结
- 自定义 JSON 数据源:避免调用接口,加载快,操作自由。
- 组件封装:分离视图和业务,复用更高。
- 联动逻辑:根据父节点变更动态更新下级列表。
通过以上方法,即可实现一个轻量、可维护、适配线下环境的省市区三级联动组件。欢迎分享与交流!
正文到此结束
- 本文标签: 微信小程序 省市区三级联动
- 本文链接: https://code.itptg.com/article/25
- 版权声明: 本文由老魏原创发布,转载请遵循《署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)》许可协议授权