下,使用u-picker封装省市区选择器独立组件

时间:2025-02-23 07:32:24
<template> <view class="addressPicker"> <u-picker :show="shows" ref="uPicker" :defaultIndex="defaultIndex" :columns="columns" keyName="name" @change="changeHandler" @cancel="cancel" @confirm="confirm"></u-picker> </view> </template> <script> import address from '@/utils/' export default { name: "addressPicker", props: { show: { type: Boolean, default: false, }, defaultIndex: { type: Array, default: () => { return [0, 0, 0] }, } }, watch: { show: { handler(newVal) { this.shows = newVal; }, // deep: true, //true 深度监听 immediate: true, //声明后立刻调用 } }, data() { return { shows: false, columns: [], //省份数据显示,三级联动需要三维数组,展示初始数据 columnData: [], //市数据 columnDatas: [], //区地址 }; }, created() { this.initDataPicker() }, methods: { // 回调参数为包含columnIndex、value、values confirm(e) { // ('confirm', ) let address = '' if (e.value.length > 0) { e.value.forEach(item => { address += item.name }) console.log('address', address) } // = false this.$emit("confirm", address); }, // 取消 cancel(e) { console.log('cancel', e) // = false this.$emit("confirm"); }, // 初始化省份列表 initDataPicker() { //此处的province主要用作数据的初始化,即刚打开就需要进行展示的数据,这个跟第一条省份数据相关,我的第一条是北京市,所以需要columns中的三维数组,第一维度是省份数据数组,第二维度是市数据数组,第三维度是区数据数组 let province = []; //初始数据需要展示的省份 let province1 = [{ name: '市辖区', code: '1101' }]; //因为第一个市北京市,所以就直接添加北京市下辖的直辖市了 也即初始数据需要展示的市,北京市只有一个市辖区 let province2 = []; //初始数据需要展示的区域数据,也即是 北京市市辖区内的区 address.map(item => { province.push(item); }); address[0].children[0].children.map(item => { province2.push(item); }); //省数据 因为要做数据初始化,所以是三维数组 // 数据格式 [ [所有的省份数据:{},{}] , [第一个省份下的所有的市:{},{},{}] , [第一个市下面所有的区:{},{},{}] ] this.columns.push(province); this.columns.push(province1); this.columns.push(province2); // 市数据数组,筛选文件,将全国所有省下面的市数据放入数组 // 格式[ [第一个省下面所有市,{},{},{}] , [第二个省下面所有市{},{},{}] , [第三个省下面所有市{},{},{}] ] 注意,以上的第一第二对应着 columns[0] 的数据 address.map(item => { let city = []; item.children.map(item1 => { city.push(item1); }); this.columnData.push(city); }); //区数据数组 //数据格式: [ 所有省下面所有市的所有区 [ 第一个省下面所有市的区:[ [第一个省下面第一个市的所有区] , [第一个省下面第二个市的所有区] ,] , [ 第二个省下面所有市的区:[ [第二个省下面第一个市的所有区] , [第二个省下面第二个市的所有区] ,] ] let area = []; address.map((item, index) => { let area1 = []; //省下面所有市的初始化 item.children.map(item1 => { area = []; //市下面的区初始化 item1.children.map(item2 => { area.push(item2); }); area1.push(area); // 每循环一个市,添加该市下面的所有区 }); this.columnDatas.push(area1); // 每循环一个省,添加该省下面的所有市 }); }, changeHandler(e) { //城市选择时触发 const { columnIndex, //当前选择的列,省 / 市 / 区 value, // 当前选择的数组内容 values, // values为当前变化列的数组内容 index, // 当前列的下标值 indexs, // 当前选择 省 市 区的下表值 picker = this.$refs.uPicker } = e; // 当第一列值发生变化时,变化第二列和第三列的值(省份变更,市和区跟着变更) if (columnIndex === 0) { // 判断当前变更的是省还是市还是区 // picker为选择器this实例,变化第二列对应的选项 picker.setColumnValues(1, this.columnData[ index]); //设置市为该省下面的所有市,index是当前省在省份数组的下标,对应市数组中的下表就是 该省下面的所有市 的数据 picker.setColumnValues(2, this.columnDatas[index][0]); // 设置区域为该省下面第一个市下面的所有区域 } if (columnIndex === 1) { // 当第二列发生变化 变化对应的第三列 picker.setColumnValues(2, this.columnDatas[indexs[0]][index]); //同上 } } } } </script> <style lang="scss" scoped> </style>