版本说明
- vue3
- ts 语言
使用说明
- 需要准备一份省市区街道 json 数据
- 如果需要默认显示指定的省市区街道, 然后回显到 picker 选择框中, 在自定义 cityPicker 组件中需要获取省市区街道字符串 ( 例如: 四川省成都市武侯区玉林街道 )
- 调用 setDefaultValue 方法设置默认值, 详见代码
引入省市区街道 json 数据
- 先在 utils 目录下建立 city.js 文件, 存储省市区街道 json 数据, 然后导出 export, 方便 cityPicker 组件获取
- city.js 文件 自取
链接: https://pan.baidu.com/s/12_xTL9u3-3mGMF-SgJib-g?pwd=b9xn
提取码: b9xn
cityPicker 组件完整代码
<template>
<view>
<picker mode="multiSelector" :range="multiArray" :value="selectedIndex" @change="onChange" @columnchange="onColumnChange" @cancel="pickerCancel(addressInfo)">
<view class="picker" v-if="selectedValue[0]">
{{ selectedValue[0] + '-' + selectedValue[1] + '-' + selectedValue[2] + '-' + selectedValue[3] }}
</view>
<view v-else></view>
</picker>
</view>
</template>
<script lang="ts">
import { defineComponent, ref, getCurrentInstance, watch, onMounted, inject } from 'vue';
import jsonData from '../../utils/city.js';
export default defineComponent({
props: ['address'],
setup(props) {
const { proxy } = getCurrentInstance();
const multiArray = ref([[], [], [], []]);
const selectedIndex = ref([0, 0, 0, 0]);
const selectedValue = ref(['', '', '', '']);
const addressInfo = ref([]);
const areaData = jsonData;
onMounted(() => {
initMultiArray();
// 设置默认值
let address = uni.getStorageSync('defautAddress');
const regex = /(.+省)(.+市)(.+区)(.+)/;
address = address.match(regex);
const newAddreeArray = [];
newAddreeArray.push(address[1]);
newAddreeArray.push(address[2]);
newAddreeArray.push(address[3]);
newAddreeArray.push(address[4]);
addressInfo.value = newAddreeArray;
selectedValue.value = addressInfo.value;
pickerCancel(addressInfo.value);
});
const pickerCancel = (editScreenVis) => {
// console.log('editScreenVis', editScreenVis);
if (editScreenVis && editScreenVis.length > 0) {
setDefaultValue(editScreenVis[0], editScreenVis[1], editScreenVis[2], editScreenVis[3]);
} else {
setDefaultValue('四川省', '成都市', '武侯区', '玉林街道');
}
};
//初始数据
const initMultiArray = () => {
const provinces = Object.keys(areaData);
const cities = Object.keys(areaData[provinces[0]] || {});
const districts = Object.keys(areaData[provinces[0]][cities[0]] || {});
const streets = areaData[provinces[0]][cities[0]][districts[0]] || [];
multiArray.value = [provinces, cities, districts, streets];
};
const setDefaultValue = (defaultProvince: string, defaultCity: string, defaultDistrict: string, defaultStreet: string) => {
const provinceIndex = multiArray.value[0].indexOf(defaultProvince);
let defaultCityArray = [];
let defaultDistrictArray = [];
let defaultStreetArray = [];
let cityArray = [];
let districtArray = [];
let streetArray = [];
let cityIndex = 0;
let streetIndex = 0;
let districtIndex = 0;
for (let key in areaData) {
if (key == defaultProvince) {
defaultCityArray = areaData[key];
}
}
for (let key in defaultCityArray) {
cityArray.push(key);
multiArray.value[1] = cityArray;
cityIndex = multiArray.value[1].indexOf(defaultCity);
if (key == defaultCity) {
defaultDistrictArray = defaultCityArray[key];
}
}
for (let key in defaultDistrictArray) {
districtArray.push(key);
multiArray.value[2] = districtArray;
districtIndex = multiArray.value[2].indexOf(defaultDistrict);
if (key == defaultDistrict) {
defaultStreetArray = defaultDistrictArray[key];
}
}
multiArray.value[3] = defaultStreetArray;
streetIndex = multiArray.value[3].indexOf(defaultStreet);
let arr = [];
arr.push(provinceIndex);
arr.push(cityIndex);
arr.push(districtIndex);
arr.push(streetIndex);
selectedIndex.value = arr;
};
const onColumnChange = (e: any) => {
const { column, value } = e.detail;
selectedIndex.value[column] = value;
if (column === 0) {
// 省份变化
selectedIndex.value = [value, 0, 0, 0];
} else if (column === 1) {
// 城市变化
selectedIndex.value = [selectedIndex.value[0], value, 0, 0];
} else if (column === 2) {
// 区县变化
selectedIndex.value = [selectedIndex.value[0], selectedIndex.value[1], value, 0];
}
updateMultiArray();
};
const updateMultiArray = () => {
const currentProvince = multiArray.value[0][selectedIndex.value[0]];
const currentCity = multiArray.value[1][selectedIndex.value[1]];
const currentDistrict = multiArray.value[2][selectedIndex.value[2]];
const newCities = Object.keys(areaData[currentProvince] || {});
const newDistricts = newCities.length > 0 ? Object.keys(areaData[currentProvince]?.[currentCity] || {}) : [];
const newStreets = newDistricts.length > 0 ? areaData[currentProvince]?.[currentCity]?.[currentDistrict] || [] : [];
multiArray.value = [multiArray.value[0], newCities, newDistricts, newStreets];
};
const onChange = (e: any) => {
const { value } = e.detail;
selectedIndex.value = value;
selectedValue.value = [multiArray.value[0][value[0]], multiArray.value[1][value[1]], multiArray.value[2][value[2]], multiArray.value[3][value[3]]];
};
return {
multiArray,
selectedValue,
onColumnChange,
onChange,
selectedIndex,
setDefaultValue,
pickerCancel,
addressInfo
};
}
});
</script>
<style scoped>
.picker {
width: 100%;
}
</style>