使用uView2.X的 Picker 选择器封装地区选择器

2,243 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第4天,点击查看活动详情

Picker 选择器的介绍这里就不过多介绍了,基本使用的话只需要一个布尔值控制显示与隐藏,一个数组为选择项就行了。

image-20221218153206051.png

地区选择器需要用到多列联动功能,大家可以仔细阅读官网例子,数据也是有布尔值,一个选择项数组,以及第二列选择项的数组,所以,第一步就需要把数据转化成这种形式

image-20221218153741845.png

首先分析一下我的地区数据,第一层是省,name字段是省的名字,children字段是省下面的市,children的children字段是市下面的区,现在需要把所有省、市、区取出来单独存放在不同的数组里面。

image-20221218154146896.png

<u-picker ref="uPicker" :defaultIndex="indexs" :columns="columns" @confirm="confirm" @change="changeHandler">
</u-picker>
​
addressData: {
    id: "",
    province: "",
    city: "",
    area: "",
    detail: "",
    userName: "",
    phone: "",
    isDefault: false
}, //地址数据
columns: [], //当前的选择项
province: [], //省数据
city: [], //市数据
area: [], //区数据
indexs:[], //默认地区下标
formatData() {
    this.province = area.map(t => {
        return {
            name: t.name,
            areaId: t.areaId
        }
    })
    this.city = area.map(t => t.children.map(v => {
        return {
            name: v.name,
            areaId: v.areaId
        }
    }))
    this.area = area.map(t => t.children.map(v => v.children.map(i => {
        return {
            name: i.name,
            areaId: i.areaId
        }
    })))
    console.log('省', this.province);
    console.log('市', this.city);
    console.log('区', this.area);
    //默认显示数据
    this.columns = [
        this.province.map(res => res.name),
        this.city[0].map(res => res.name),
        this.area[0][0].map(res => res.name)
    ]
},

当组件加载出来后,就可以调用 formatData 方法,把数据转化成想要的数据,最后把默认值赋给 columns 字段,效果大概就是这样的

image-20221218154813508.png

下一步就是当选择项改变的时候数据联动,绑定 change 事件 ,定义changeHandler 方法

changeHandler(e) {
    const {
        columnIndex, //当前改变值的列下标
        value,
        values, // values为当前变化列的数组内容
        indexs, //当前地区值下标
        picker = this.$refs.uPicker
    } = e
    console.log("value", value)
    console.log(values)
    console.log(e)
    console.log(indexs)
    //columnIndex代表第几列,意思是下标为0的列发生变化
    if (columnIndex === 0) {
        console.log(this.area[indexs[0]]);
        picker.setColumnValues(1, this.city[indexs[0]].map(v => v.name))
        picker.setColumnValues(2, this.area[indexs[0]][0].map(v => v.name))
    }
    if (columnIndex === 1) {
        console.log(this.area[indexs[0]][indexs[1]].map(v => v.name))
        picker.setColumnValues(2, this.area[indexs[0]][indexs[1]].map(v => v.name))
    }
},

比较重要的是 picker.setColumnValues() ,当省发生改变是,市和区都要发生对应的变化,当市发生变化时,需要变化对应的区,绑定确认事件 confirm 的回调参数就是想要的地区信息了。

到这也还不算完,当后台给了我一个地区,我要怎么让这个选择器打开默认值就是后台返回给我的地区呢?

image-20221218160631855.png

官网中提供了一个 defaultIndex 配置项,它是一个数组,我们只需要将后台返回的地区,在数据中对应的下标配置进去就可以了。

formatData 方法最后加入:

//数据回显
if (this.addressData.province && this.addressData.city && this.addressData.area) {
    //省索引
    let pIdx = this.province.findIndex(v => v.name == this.addressData.province);
    //根据省索引设置默认市数据
    this.columns[1] = this.city[pIdx].map(res => res.name)
    //市索引
    let cIdx = this.city[pIdx].findIndex(v => v.name == this.addressData.city);
    //根据市索引设置默认区数据
    this.columns[2] = this.area[pIdx][cIdx].map(res => res.name)
    //区索引
    let aIdx = this.area[pIdx][cIdx].findIndex(v => v.name == this.addressData.area);
    this.indexs = [pIdx, cIdx, aIdx];
    console.log(pIdx, cIdx, aIdx);
}

到这一步也就全部完成了!

组件发布在插件市场了,感兴趣的 jym 可以下载尝试 地区选择器