uniapp的级联选择器如何做异步数据
时间: 2025-07-05 07:11:06 浏览: 1
### UniApp 中实现级联选择器异步数据加载
在 UniApp 中使用 `cascader` 组件时,如果需要支持异步数据加载,则需确保每次展开节点时都能触发相应的数据获取逻辑。下面是一个完整的解决方案。
#### 1. 数据结构设计
为了使级联选择器能够正常工作,服务器返回的数据应遵循特定格式:
```json
[
{
"value": "node_value",
"label": "Node Label",
"children": [] // 子节点列表,默认为空数组表示未加载
}
]
```
当某个节点被点击或展开时,会调用对应的 API 获取子节点信息,并更新到当前节点的 children 属性下[^1]。
#### 2. 页面模板定义
页面上通过 `<picker>` 或者其他形式展示级联选择器控件,绑定 value 和 options 参数用于显示已选中的路径以及可选项集合。
```html
<template>
<view class="container">
<!-- 使用 picker 来模拟 cascader -->
<picker mode="multiSelector" @columnchange="bindMultiPickerColumnChange"
:range-key="'label'" :value="indexArr" range="optionsList">
<button type="default">请选择</button>
</picker>
{{selectedValue}}
</view>
</template>
```
#### 3. Vue 实例配置
初始化时设定好默认参数,在 methods 中编写处理多列联动变化事件 bindMultiPickerColumnChange 方法来负责发起网络请求并填充新一层的数据源。
```javascript
export default {
data() {
return {
indexArr: [], // 当前各级索引位置
selectedValue: '', // 已经选定的内容字符串拼接结果
optionsList: [[]], // 各层菜单项组成的二维数组
loadingMap: new Map(), // 记录正在加载状态防止重复请求
};
},
onLoad(){
this.loadNextLevel(0);
},
methods: {
/**
* 加载指定层级之后的所有级别数据
*/
async loadNextLevel(level){
const key = level.toString();
if(this.loadingMap.has(key)){
console.log(`level ${key} is already being loaded`);
return;
}
try{
this.loadingMap.set(key, true);
let resp;
switch(level){
case 0:
resp = await uni.request({
url:'/api/getProvinces',
});
break;
case 1:
const provinceCode = this.optionsList[level-1][this.indexArr[level-1]].code;
resp = await uni.request({
url:`/api/getCities?province=${provinceCode}`,
});
break;
case 2:
const cityCode = this.optionsList[level-1][this.indexArr[level-1]].code;
resp = await uni.request({
url:`/api/getDistricts?city=${cityCode}`,
});
break;
default:
throw Error('Unexpected Level');
}
const newData = resp.data.map(item => ({
label:item.name,
code:item.id,
children:[]
}));
while(optionsList.length>level+1){
optionsList.pop();
}
optionsList.push(newData);
this.$set(this,'optionsList', [...this.optionsList]);
}catch(e){
console.error(e.message);
}finally{
this.loadingMap.delete(key);
}
},
/**
* 多列选择器改变回调函数
*/
bindMultiPickerColumnChange(event) {
const columnIdx = event.detail.column;
const newValueIndex = event.detail.value;
// 更新对应级别的索引值
this.$set(this.indexArr,columnIdx,newValueIndex);
// 如果不是最后一列则继续向下加载更多层次的数据
if(columnIdx !== this.optionsList.length - 1){
this.loadNextLevel(columnIdx + 1);
}
// 构建最终的选择串
this.selectedValue = this.indexArr.reduce((acc,idx,i)=>{
acc += `${i===0?'':'>'}${this.optionsList[i][idx].label}`;
return acc;
},'');
}
}
}
```
此方案实现了基于用户交互逐步按需加载后续层级的功能,同时也解决了初次渲染时不立即执行全部查询操作的问题。每当用户切换某一级别的选项时都会重新计算其后的所有可能分支,并且只有当这些新的分支确实存在并且尚未缓存过才会真正去访问远程服务端口取数[^2]。
阅读全文
相关推荐













