鼠鼠闯世界
鼠鼠闯世界
  • 发布:2026-02-08 19:22
  • 更新:2026-02-08 19:22
  • 阅读:12

关于如何使用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-08 19:22 负责人:无 分享
已邀请:
Ask小助手

Ask小助手 - Ask社区AI助手

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

uni-ui 的 <uni-data-picker> 已经帮你把「省-市-区」的级联、懒加载、回显三件事都封装好了,只需要把后端接口按照组件约定的格式返回即可。下面给出最小可运行示例,分三步完成:

  1. 准备后端接口(3 个)
  2. 前端绑定 <uni-data-picker>
  3. 回显已有省市区

  1. 后端接口约定
    组件在展开每一级时会自动发请求,url 规则如下:
GET /area/parent?parentId=0          -> 返回所有省份  
GET /area/parent?parentId=110000     -> 返回北京市下所有市  
GET /area/parent?parentId=110100     -> 返回北京市辖区下所有区

返回格式必须是:

{  
  "data": [  
    { "value": 110000, "text": "北京市" },  
    { "value": 120000, "text": "天津市" }  
  ]  
}

(字段只能是 value / text,不能是 id / name


  1. 前端代码
<template>  
  <view>  
    <!-- 省市区选择 -->  
    <uni-data-picker  
      v-model="addressCode"  
      :localdata="[]"  
      :map="map"  
      popup-title="请选择地区"  
      @change="onchange"  
    ></uni-data-picker>  

    <!-- 仅调试用:展示已选 -->  
    <view style="margin-top:20rpx">  
      已选:{{ addressCode }}  
    </view>  
  </view>  
</template>  

<script setup>  
import { ref } from 'vue'  

// 用于回显/提交  
const addressCode = ref([])  

// 把后端接口映射给组件  
const map = {  
  // 组件会自动把 parentId 拼到 url 后面  
  url: '/area/parent',  
  // 如果后端返回字段不是 value/text,用 textField/valueField 做映射  
  textField: 'text',  
  valueField: 'value',  
  // 返回数据路径  
  dataPath: 'data'  
}  

// 选择完成  
function onchange(e) {  
  console.log('最终选择的完整节点:', e.detail.value)  
}  
</script>

  1. 回显已有省市区
    只要给 v-model 赋值即可,例如:
// 假设数据库里存的是 [省id, 市id, 区id]  
addressCode.value = [110000, 110100, 110101]

组件会自动根据这 3 个 id 去调用 /area/parent 把对应的文本加载出来,实现回显。


  1. 常见踩坑提醒
    • 后端返回字段必须是 value / text,否则用 textField / valueField 做映射。
    • 如果接口需要分页,把分页参数写到 map 里即可,如 url: '/area/parent?pageSize=200'
    • 如果想一次性把所有数据打到前端,直接把整棵树放到 localdata 里,省掉懒加载。

这样就实现了「一级一级选」和「回显」的全部需求。

内容为 AI 生成,仅供参考

要回复问题请先登录注册