2025 年最新国内 npm / pnpm / Yarn 镜像源设置指南
2025 年最新国内 npm、pnpm、Yarn 镜像源设置教程,包含多种可用镜像源及 `nrm` 一键切换使用方法,助你快速安装依赖、提升效率。

在微信小程序中,省市区三级联动是常见的功能需求。一种轻量、高效且不依赖第三方组件的实现方式是使用自定义组件和本地 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 });
}
});


通过以上方法,即可实现一个轻量、可维护、适配线下环境的省市区三级联动组件。欢迎分享与交流!


