Deng
Deng
uniapp小程序使用picker组件实现省市区街道四级联动 | odjBlog
    欢迎来到odjBlog的博客!

uniapp小程序使用picker组件实现省市区街道四级联动

技术总结及问题解决 odjbin 1年前 (2024-11-19) 52次浏览 0个评论

版本说明

  • 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>
喜欢 (0)
[]
分享 (0)
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
已稳定运行:3年255天3小时48分