uview+uniCloud实现省市区选择

251 阅读2分钟

前言

公司最近接了一个微信小程序的新项目,其中有个地区选择在本地使用Json编译到微信小程序代码包会太大,于是便想着使用uniCloud使用uniCloud中OpenDB的中国城市的数据表

在uniCloud中新建服务空间

  1. unicloud.dcloud.net.cn/ uniCloud的地址
  2. 在云数据库中新建数据表

image.png 3. 选择opendb-city-china表进行创建

image.png

项目关联云服务

代码中获取表数据

const db = uniCloud.database()
const collection = db.collection('opendb-city-china')

具体用法可参考 doc.dcloud.net.cn/uniCloud/jq…

获取uview picker对应数据格式

const db = uniCloud.database()
const collection = db.collection('opendb-city-china')
const province = []
let { result: { data } } = await collection.get();
province = province.concat(data.filter(item => !item.parent_code));

获取省级Json 根据数据表的数据结构 没有parent_code字段的为省级

const city = []
const { result: { data: dataCity } } = await collection.where({
    parent_code: province[0].code
}).get()
city = dataCity

collection.where({字段名:"查询的值"}) 根据parent_code字段查询属于该省级的市级Json

const area = []
const { result: { data: dataArea } } = await collection.where({
    parent_code: city[0].code
}).get()
area = dataArea

根据parent_code字段查询属于该市级的区级Json

const columnsArea = [
    province.map(res => res.name),
    city.map(res => res.name),
    area.map(res => res.name)
]
const areaJson = [
    province,city,area
]

获取省市区Json之后整合成uview picker需要的渲染数组结构,还有数据数组

问题(关键)

以上请求到省级Json的时候会有一个问题 每次collection.get()默认最多数据条数为100,那么我们会获取不到全部的省级数据(只有三条),所以我们需要使用limit(num)、skip()、count()实现翻页查询的效果查出所有的省级数据

const province = []
let limit = 1000   // 每次查询数量
let offset = 0    // 跳过数量
let { result: { total } } = await collection.count()
do {
    let { result: { data } } = await collection.skip(offset).limit(limit).get();
    province = province.concat(data.filter(item => !item.parent_code)); // 将查询到的数据添加到列表中	 
    offset += limit; // 更新跳过量
} while (offset < total);

这样循环查询才能查询到所有的省级数据 这样我们就能查出所有省市区的数据

picker滚动时更新渲染数据

const changeArea = (e) => {
    const { columnIndex, index } = e
    if (columnIndex === 0) {
        getAreaJson(areaJson[0][index].code)
    } else if (columnIndex === 1) {
        getAreaJson(true, areaJson[1][index].code)
    }
}

columnIndex是操作列 index是操作列的选中项 如果操作列为省级数据则传选中省级code 如果操作列是市级数据则传选中市级code和默认一个不再请求省级数据的参数 组件添加:immediateChange="false"阻止滚动立即触发组件change事件

完整代码

const columnsArea = ref([])
const areaJson = ref([])
const getAreaJson=(province?:string|boolean,city?:string|boolean)=>{
    const db = uniCloud.database() 
    const collection = db.collection('opendb-city-china')
    if(!province){
        const province = [] let limit = 1000 // 每次查询数量 
        let offset = 0 // 跳过数量 
        let { result: { total } } = await collection.count() 
        do { 
            let { result: { data } } = await collection.skip(offset).limit(limit).get(); 
            province = province.concat(data.filter(item => !item.parent_code)); // 将查询到的数据添加到列表中 
            offset += limit; // 更新跳过量 
        } while (offset < total);
    }
    if(!city){
        const city = [] 
        const { result: { data: dataCity } } = await collection.where({ parent_code: province || province[0].code }).get() 
        city = dataCity
    }
    const area = [] 
    const { result: { data: dataArea } } = await collection.where({ city: city || city[0].code }).get()
    area = dataArea
    
    columnsArea.value = [
        province.map(res => res.name),
        city.map(res => res.name),
        area.map(res => res.name)
    ]
    areaJson.value = [
        province,city,area
    ]
}

const changeArea = (e) => {
    const { columnIndex, index } = e
    if (columnIndex === 0) {
        getAreaJson(areaJson.value[0][index].code)
    } else if (columnIndex === 1) {
        getAreaJson(true, areaJson.value[1][index].code)
    }
}