uniapp 用 uView 组件库中的u-picker 实现地区的 省-市-区 三级联动
组件的引入就不多赘述了 直接看使用方法
地址我是引入的json文件数据结构大概是这个样子
例1
例2
1,先做个按钮做弹窗显示
<u-cell :border="true" > <text slot="title" > 区域</text> <view slot="right-icon" @tap="showLocal = true"> <text >{{ local === '' ? '请选择区域所在地' : local }}</text> </view> </u-cell>
2.使用组件
<u-picker @cancel="showLocal = false" @close="showLocal = false" :show="showLocal" :columns="addressColumns" @confirm="localConfirm" title="请选择所在地" keyName="name" itemHeight="80" closeOnClickOverlay ref="uPicker" @change="changeHandler" :defaultIndex="defaultAddress" immediateChange ></u-picker>
3,用到的变量
import areas from '@/utils/areas.json'//引入原始数据 export default { data(){ return { local: '', //区域 localCode: '', //这个变量看个人需求使用 showLocal: false, //是否展示弹出层 addressColumns: [], //数据数组 defaultAddress: [], //默认选中 (回填时或者初次显示默认选中) addressData: areas, //原始数据 (引入的json文件) } } }
4,初始化数据
onShow() { //省的数组 const provinceData = areas.map(e => { return { name: e.name, code: e.code }//这里可以直接return e.name 这里我是要用到code所以才用对象包起来的 下面的市 区 也一样 }) //市的数组 const cityData = areas.map(e => { const arr = [] arr.push( e.areas.map(c => { return { name: c.name, code: c.code } }) ) return arr }) //区的数组 const areaData = areas.map(e => { const arr = [] arr.push( e.areas.map(c => c.areas.map(d => { return { name: d.name, code: d.code } }) ) ) return arr }) const arr = [provinceData, cityData[0][0], areaData[0][0][0]] this.addressColumns = arr //将得到的3个数组 的第一个市的所有数据赋值 作为初始数据 },
5.数据变更时的方法
changeHandler(e) { //分别表示选中的列 , 该列的第几个,选中的3列的第几个的数组,组件本身 const { columnIndex, index, indexs, picker = this.$refs.uPicker } = e //如果改变的是第一列 if (columnIndex === 0) { const children1 = this.addressData[index].areas.map(e => { return { name: e.name, code: e.code } }) picker.setColumnValues(1, children1) //更换 第二列数据 const children2 = this.addressData[index].areas[indexs[1]].areas.map(e => { return { name: e.name, code: e.code } }) picker.setColumnValues(2, children2) //更换 第三列数据 } if (columnIndex === 1) { //如果改变的是第二列 const children3 = this.addressData[indexs[0]].areas[indexs[1]].areas.map(e => { return { name: e.name, code: e.code } }) picker.setColumnValues(2, children3) //更换 第三列数据 } },
6.点击确认时的方法
localConfirm(e) { //显而易见 不多赘述 this.local = `${e.value[0].name}-${e.value[1].name}-${e.value[2].name}` this.localCode = `${e.value[0].code}-${e.value[1].code}-${e.value[2].code}` this.showLocal = false },
7.数据的回填
//已经知道了 this.local ='省-市-区'初始弹窗时默认选中改值 backfill(temp) { temp = item.area.split('-') let index, index1, index2 = 0 let arr, arr1, arr2 = [] //匹配省市区对应每列的第几个 this.addressData.forEach((item, i) => { if (item.name == temp[0]) { index = i item.children.forEach((val, ind) => { if (val.name == temp[1]) { index1 = ind val.children.forEach((e, n) => { if (e.name == temp[2]) { index2 = n } }) } }) } }) arr = this.addressData.map(e => { return { name: e.name, code: e.code } }) arr1 = this.addressData[index].children.map(e => { return { name: e.name, code: e.code } }) arr2 = this.addressData[index].children[index1].children.map(e => { return { name: e.name, code: e.code } }) //反推出3列的数组数据 this.addressColumns = [arr, arr1, arr2] // 赋值给 默认初始选中 this.defaultAddress = [index, index1, index2] }
这是其中的json文件
链接:https://pan.baidu.com/s/1_heSAGHJnTe-343fRmbOPA
提取码:hmky