鼠鼠闯世界
鼠鼠闯世界
  • 发布:2026-02-09 09:03
  • 更新:2026-02-09 09:03
  • 阅读:84

如何使用uni-ui里的uni-data-picker级联选择器实现省市区

分类:uni-app

关于uni-ui里的uni-data-picker级联选择器实现省市区

const getProvinceList = async () => {
try {
const params = { size: 200 };
const res = await HttpUtil.doGet('url', params);
if (Array.isArray(res.dataList)) {
const map = res.dataList.map((item: any) => {
return {
label: item.name,
value: item.id
};
});
provinceList.value = map;

    // 默认选择第一个省份    
    if (map.length > 0) {    
        posValue.value = [0, 0, 0];    
        const firstProvinceId = map[0].value;    
        getCityList(firstProvinceId).then(() => {    
            if (cityList.value.length > 0) {    
                getDistrictList(cityList.value[0].value);    
            }    
        });    
    }    
}    

} catch (err) {
console.error('获取省份列表失败:', (err as Error).message);
}
};

const getCityList = async (provinceId: number) => {
if (!provinceId || typeof provinceId !== 'number' || provinceId <= 0) {
uni.showToast({ title: '请选择有效省份', icon: 'none' });
return;
}
try {
const params = { size: 150 };
const res = await HttpUtil.doGet(url, params);
if (Array.isArray(res.dataList)) {
const map = res.dataList.map((item: any) => {
return {
label: item.name,
value: item.id
};
});
cityList.value = map;
}
} catch (err) {
console.error(获取城市列表失败(省份ID:${provinceId}):, (err as Error).message);
}
};

const getDistrictList = async (cityId: number) => {
try {
const params = { size: 150 };
const res = await HttpUtil.doGet(url, params);
if (Array.isArray(res.dataList)) {
const map = res.dataList.map((item: any) => {
return {
label: item.name,
value: item.id
};
});
districtList.value = map;
}
} catch (err) {
console.error(获取数据失败:, (err as Error).message);
}
};

我应该如何实现?省份获取到后拿省份的id去city拿市,再从市的id拿区,要求能够一级一级的选择,以及回显

我需要做本地的,因为后端数据给的格式需要我进行转换

2026-02-09 09:03 负责人:无 分享
已邀请:
Ask小助手

Ask小助手 - Ask社区AI助手

欢迎到专业群( uni-ui官方技术交流群 ) 咨询,群中有相关专业的管理员和群友。

uni-data-picker 本身就是一个“级联懒加载”的 datacom 组件,官方已经帮你把“省-市-区”三级联动、回显、本地/云端数据几种场景都封装好了。
你现在的诉求是“本地数据 + 逐级加载 + 回显”,下面给出可直接落地的最小实现步骤,全部基于官方文档与示例整理,无额外推测。


  1. 安装组件
    在 HBuilderX → 插件市场搜索并安装 uni-data-picker(如果已装可跳过)。

  2. 准备本地省市区 JSON
    把后端返回的扁平数据一次性转成组件需要的树形结构(只转一次即可,放在 @/static/area.json@/utils/area.js)。
    示例转换函数(伪代码):

// utils/area.js  
export const buildTree = (list) => {  
  const map = new Map()  
  list.forEach(item => map.set(item.id, { ...item, children: [] }))  
  const tree = []  
  list.forEach(item => {  
    const node = map.get(item.id)  
    if (item.parentId === 0) {  
      tree.push({ text: item.name, value: item.id, children: node.children })  
    } else {  
      const parent = map.get(item.parentId)  
      parent && parent.children.push({ text: item.name, value: item.id, children: node.children })  
    }  
  })  
  return tree  
}
  1. 页面使用
<template>  
  <view>  
    <!-- 本地数据 + 级联 -->  
    <uni-data-picker  
      v-model="areaCode"  
      :localdata="areaTree"  
      popup-title="请选择省市区"  
      @change="onChange"  
    />  
  </view>  
</template>  

<script setup>  
import { ref, onMounted } from 'vue'  
import { buildTree } from '@/utils/area.js'  

const areaCode = ref([])          // 用于回显/取值  
const areaTree = ref([])          // 本地树形数据  

onMounted(async () => {  
  // 1. 一次性拿全部扁平数据(本地 JSON 或接口)  
  const raw = await uni.request({ url: '/static/area.json' })  
  areaTree.value = buildTree(raw.data)  

  // 2. 回显:把已有省市区 id 数组写进 v-model  
  // 例:已有地址 110000-110100-110105  
  areaCode.value = [110000, 110100, 110105]  
})  

const onChange = (e) => {  
  console.log('最终选择:', e.detail.value) // [省id, 市id, 区id]  
}  
</script>
  1. 关键点说明
    • localdata 接受树形结构,组件会自动懒加载子级。
    • v-model 绑定一个数组即可回显,数组顺序即“省-市-区”的 id。
    • 如果后端是分页接口,可在 @nodeclick 里手动把下一级数据塞进对应节点的 children,官方示例有完整写法(见 本地数据)。
    • 若以后想切云端,直接把 collection="opendb-city-china" 等属性替换即可,无需改交互层。

这样就实现了“本地省市区级联 + 逐级加载 + 回显”的全部需求。

内容为 AI 生成,仅供参考

要回复问题请先登录注册