1.模板渲染及事件绑定
<uni-forms-item label="地址" name="address">
<picker mode="multiSelector" :range="areaData" range-key="name" :value="multiIndex"
@change="pickerChange" @columnchange="pickerColumnchange">
<view class="myarea">{{select}}</view>
</picker>
</uni-forms-item>
说明: mode="multiSelector" 表示多列选择(省、市、区), :range="areaData" 表示省市区相应的数据源, range-key="name" 表示数据源中的数据是数组包对象,则使用该属性绑定对象中的属性名渲染到页面中(本数据[{id:1, name:'北京',pid:1000}]); :value="multiIndex"表示省市区选中的索引;@columnchange="pickerColumnchange" 表示绑定切换省市区时触发的事件; @change="pickerChange" 表示选择完成后确定事件; <view class="myarea">{{select}}</view> 表示选择后的结果
2.相应的数据源和变量准备(本次使用的是vue3语法糖)
<script setup>
import {reactive,ref} from 'vue'
const areaData = ref([[],[],[]]) // 是一个二维数组,二维数组中的第一个数组为省的数据,第二个为市的数据,第三个为区的数据
const pdata = ref([]) // 省数据
const cdata = ref({}) // 市数据
const adata = ref({}) // 区数据
const multiIndex = ref([0, 0, 0]) // 选择省市区后的索引,默认为第一个索引
const select = ref('请选择地区') // 省市区选择后的结果,默认为请选择地区
</script>
3.页面加载后请求省市区数据源
const getArea = async () => {
let pro = await uni.$http.get(`获取省数据接口地址`) // 所有省的数据接口
let city = await uni.$http.get(`获取市数据接口地址`) // 所有市的数据接口
let area = await uni.$http.get(`获取区数据接口地址`) // 所有区的数据接口
pdata.value = pro.data.msg // 在变量中保存省的数据
cdata.value = city.data.msg // 在变量中保存市的数据
adata.value = area.data.msg // 在变量中保存区的数据
areaData.value[0] = pdata.value // 把省的数据添加到数据源的第一个位置
areaData.value[1] = cdata.value[pdata.value[0].pid] // 通过把第一个省的id把市的数据添加到数据源的第二个位置
areaData.value[2] = adata.value[cdata.value[pdata.value[0].pid][0].pid] // 通过把第一个省的id且把它应下第一个市的id找到,把区的数据添加到数据源的第三个位置
}
getArea()
// 省的数据结构如下:
[
{
"id": 1,
"name": "北京市",
"pid": "110000"
},
{
"id": 2,
"name": "天津市",
"pid": "120000"
},
{
"id": 3,
"name": "河北省",
"pid": "130000"
},
{
"id": 4,
"name": "山西省",
"pid": "140000"
}
]
// 市的数据结构如下:
{
"110000": [
{
"id": 1,
"name": "市辖区",
"pid": "110100"
},
{
"id": 2,
"name": "县",
"pid": "110200"
}
],
"120000": [
{
"id": 3,
"name": "市辖区",
"pid": "120100"
},
{
"id": 4,
"name": "县",
"pid": "120200"
}
],
"130000": [
{
"id": 5,
"name": "石家庄市",
"pid": "130100"
},
{
"id": 6,
"name": "唐山市",
"pid": "130200"
},
{
"id": 7,
"name": "秦皇岛市",
"pid": "130300"
},
{
"id": 8,
"name": "邯郸市",
"pid": "130400"
},
{
"id": 9,
"name": "邢台市",
"pid": "130500"
},
{
"id": 10,
"name": "保定市",
"pid": "130600"
},
{
"id": 11,
"name": "张家口市",
"pid": "130700"
},
{
"id": 12,
"name": "承德市",
"pid": "130800"
},
{
"id": 13,
"name": "沧州市",
"pid": "130900"
},
{
"id": 14,
"name": "廊坊市",
"pid": "131000"
},
{
"id": 15,
"name": "衡水市",
"pid": "131100"
}
]
}
// 区的数据结构如下:
{
110100: [{
id: 1,
name: "东城区"
}, {
id: 2,
name: "西城区"
}, {
id: 3,
name: "崇文区"
}, {
id: 4,
name: "宣武区"
}, …],
…
}
110100
: [{
id: 1,
name: "东城区"
}, {
id: 2,
name: "西城区"
}, {
id: 3,
name: "崇文区"
}, {
id: 4,
name: "宣武区"
}, …]
110200
: [{
id: 17,
name: "密云县"
}, {
id: 18,
name: "延庆县"
}]
120100
: [{
id: 19,
name: "和平区"
}, {
id: 20,
name: "河东区"
}, {
id: 21,
name: "河西区"
}, {
id: 22,
name: "南开区"
}, …],
}
4.切换省市区数据时,对应数据改变
const pickerColumnchange = (e) => {
// 第几列滑动
console.log("第几列滑动 = " + e.detail.column)
// 第几列滑动选中的下标
console.log("第几列滑动选中的下标 = " + JSON.stringify(e.detail.value))
// 第一列滑动
if (e.detail.column == 0) {
// 滑动的是第一列:省 滑动省需要改变市和区的数据
multiIndex.value[0] = e.detail.value // 第一个位置把选中的省索引存储起来
// 重新绑定市的数据
console.log(cdata.value[pdata.value[e.detail.value].pid]);
areaData.value[1] = cdata.value[pdata.value[e.detail.value].pid]
areaData.value[2] = adata.value[cdata.value[pdata.value[e.detail.value].pid][0].pid] // 重新绑定区的数据
} else if (e.detail.column == 1) {
// 滑动第二列是市的数据:市改变只需要改变区的数据
multiIndex.value[1] = e.detail.value // 第二个位置把选中的市索引存储起来
areaData.value[2] = adata.value[areaData.value[1][e.detail.value].pid]
} else {
multiIndex.value[2] = e.detail.value // 第三个位置把选中的区索引存储起来
}
}
5.选好省市区确定事件
const pickerChange = (e) => {
console.log('picker发送选择改变,携带值为', e.detail)
multiIndex.value = e.detail.value
// 根据获取的索引找到对应的名称赋值给select渲染到页面中
select.value = areaData.value[0][multiIndex.value[0]].name + ' ' + areaData.value[1][multiIndex.value[1]].name + ' ' + areaData.value[2][multiIndex.value[2]].name
}