iView Cascader如何动态加载省市区数据?

码农明月 阅读 14

我用iView的Cascader做省市区三级联动,但数据量太大不想一次性加载。官方文档说支持动态加载,但我试了on-change事件里去请求下一级数据,结果选完省之后市没出来,控制台也没报错。

我这样写是不是不对?比如在loadData回调里更新options

methods: {
  handleLoadData(item, callback) {
    if (item.level === 0) {
      // 模拟请求市级
      setTimeout(() => {
        item.children = [{ value: 'shanghai', label: '上海市', level: 1 }];
        callback();
      }, 300);
    }
  }
}
我来解答 赞 1 收藏
二维码
手机扫码查看
1 条解答
利芹
利芹 Lv1
你的问题在于用了 on-change 而不是 loadData 属性,而且初始数据的 children 不能直接有值,得是空数组。

Cascader 的动态加载是通过 loadData prop 实现的,不是 on-change 事件。

正确的写法:

<template>
<Cascader :data="options" :loadData="loadData" v-model="value"></Cascader>
</template>

<script>
export default {
data() {
return {
value: [],
// 初始只传省,数据要有 children: [] 表示可展开
options: [
{ value: 'beijing', label: '北京市', children: [] },
{ value: 'shanghai', label: '上海市', children: [] }
]
}
},
methods: {
loadData(item, callback) {
// item 就是当前选中的节点
if (item.value === 'beijing') {
// 模拟请求北京下的区
setTimeout(() => {
const data = [
{ value: 'chaoyang', label: '朝阳区', children: [] },
{ value: 'haidian', label: '海淀区', children: [] }
];
item.children = data; // 直接赋值
callback(); // 关键:必须调用 callback 通知组件更新
}, 300);
} else if (item.value === 'shanghai') {
setTimeout(() => {
const data = [
{ value: 'pudong', label: '浦东新区', children: [] },
{ value: 'huangpu', label: '黄浦区', children: [] }
];
item.children = data;
callback();
}, 300);
}
}
}
}


几个关键点:

1. 初始 options 里的 children 必须写成空数组 [],不能省略,也不能有值。如果不写 children,Cascader 会认为这是叶子节点,不会触发 loadData

2. loadData 函数接收两个参数:item(当前节点)和 callback()。拿到数据后赋值给 item.children,然后一定要调用 callback()

3. 不是用 on-change 事件,在 loadData 里面直接处理就行

4. 如果你想判断层级,可以用 item.level 或者根据 value 去判断

代码放这了,你对照看下区别在哪。
点赞
2026-03-17 10:02