需要实现的需求
- 数据渲染使用懒加载
- 点击任意一级都可返回,不需要一直点到最后一级
- 编辑或者查看功能,回显之前选择的数据
实例解析
dom 元素
<el-cascaderv-model="value":options="options":props="props":key="num"@change="chaangeFunc"ref="refHandle"></el-cascader>
- value - 级联选择器绑定的数据
- options - 级联选择器列表数据
- props - 级联选择器配置内容
- num - 为级联选择器设置节点,后续在数据变化时,可以更新节点通知 DOM 更新
- chaangeFunc - 监听级联选择器的选择事件
模拟接口
// 模拟接口数据
// level:层级,key:用上一级查下一级参数使用的标识
getTempData(level, key) {return new Promise((resolve, reject) => {let result = []; // 最终要返回的数据if (level == 1) {// 一级的数据result = [{ label: "测试1", value: 1, level: 1 },{ label: "测试2", value: 2, level: 1 },];}if (level == 2) {// 二级的数据if (key == 1) {// "测试1" 查回来的子数据result = [{ label: "测试1-1", value: 11, level: 2 },{ label: "测试1-2", value: 12, level: 2 },{ label: "测试1-3", value: 13, level: 2 },];}}if (level == 3) {// 二级的数据if (key == 11) {// "测试1-1" 查回来的子数据result = [{ label: "测试1-1-1", value: 111, level: 3 },{ label: "测试1-1-2", value: 112, level: 3 },{ label: "测试1-1-3", value: 113, level: 3 },];}}setTimeout((item, index) => {console.log("级联请求到的数据", result);// 做一个延时,模拟接口数据返回resolve(result);}, 1000);});
}
// 完整的数据结构
// [{
// label: "测试1",
// value: 1,
// children: [
// {
// label: "测试1-1",
// value: 11,
// children: [
// { label: "测试1-1-1", value: 111 },
// { label: "测试1-1-2", value: 112 },
// { label: "测试1-1-3", value: 113 },
// ],
// },
// { label: "测试1-2", value: 12 },
// { label: "测试1-3", value: 13 },
// ],
// },
// { label: "测试2", value: 2, children: [] },]
渲染数据
- 默认请求一级数据
// 默认请求一级数据
this.getTempData(1).then((dataLev1) => {this.options = dataLev1;
});
- 级联选择器懒加载函数
checkStrictly
是否严格的遵守父子节点不互相关联
boolean
lazyLoad
加载动态数据的方法,仅在 lazy 为 true 时有效
function(node, resolve),node 为当前点击的节点,resolve 为数据加载完成的回调(必须调用)
props: {checkStrictly: true, // 取消父节点与子节点的严格关联,可以任意选中任何一级作为结束lazy: true,lazyLoad: (node, resolve) => {let result = node.data;console.log("点击的节点数据", result);if (result) {if (result.level != 3) {// 如果当前点击的不是第三级,则需要去调用接口查询数据this.getTempData(Number(result.level) + 1, result.value).then((sourceData) => {let data = [];if (sourceData && sourceData.length > 0) {data = sourceData;}// 将获取到的数据抛出resolve(data);});} else {resolve([]);}} else {}},
},
- 效果
- 默认渲染一级
- 点击请求二级
- 再点击请求三级
- 选中任意一级都能返回
- 默认渲染一级
// 如果需要在选中后关闭级联弹层,监听 change 事件即可
chaangeFunc() {console.log("触发了change", this.value);// 选中节点后,关闭下拉this.$refs.refHandle.dropDownVisible = false;
}
数据回显
- 第一步,获取级联下拉列表的 options,不需要全部渲染,只需要渲染被选中的部分的那一条链路
- 第二步,为级联选择器绑定的 value 赋值
- 第三步,为最后一级添加 leaf 属性,告诉结构树此节点为末级节点
getDetail() {let detailList = [1, 11, 111]; // 模拟获取到的需要渲染的节点数据this.getTempData(1).then((dataLev1) => {this.options = dataLev1;console.log("渲染完了一级");this.options.map((itemLev1, indexLev1) => {if (itemLev1.value == detailList[0]) {console.log("匹配到一级选中内容,开始查询二级");this.getTempData(2, itemLev1.value).then((dataLev2) => {if (dataLev2 && dataLev2.length > 0) {console.log("查询到了二级数据,继续向下查询");this.$set(itemLev1, "children", dataLev2);console.log("渲染完了二级");itemLev1.children.map((itemLev2, indexLev2) => {if (itemLev2.value == detailList[1]) {console.log("匹配到二级选中内容,开始查询三级");this.getTempData(3, itemLev2.value).then((dataLev3) => {if (dataLev3 && dataLev3.length > 0) {console.log("查询到了三级数据,即最末为三级");this.$set(itemLev2, "children", dataLev3);itemLev2.children.map((itemLev3, indexLev3) => {console.log("末级添加标志位");itemLev3.leaf = "leaf";});} else {console.log("未查询到三级数据,即最末为二级");itemLev2.leaf = "leaf";}console.log("渲染完了三级");this.value = detailList;this.num += 1;});}});} else {console.log("未查询到二级数据,即最末为一级");itemLev1.leaf = "leaf";}this.value = detailList;this.num += 1;});}});});
},
- 执行渲染数据的方法 getDetail
级联请求到的数据 (2) [{…}, {…}]
渲染完了一级
匹配到一级选中内容,开始查询二级
级联请求到的数据 (3) [{…}, {…}, {…}]
查询到了二级数据,继续向下查询
渲染完了二级
匹配到二级选中内容,开始查询三级
级联请求到的数据 (3) [{…}, {…}, {…}]
查询到了三级数据,即最末为三级
末级添加标志位
渲染完了三级
完整代码
<template><div class="activeEnroll_list"><el-cascaderv-model="value":options="options":props="props":key="num"@change="chaangeFunc"ref="refHandle"></el-cascader></div>
</template><script>
export default {name: "activeEnroll_list",components: {},data() {return {num: 0,value: [],options: [// {// label: "测试1",// value: 1,// children: [// {// label: "测试1-1",// value: 11,// children: [// { label: "测试1-1-1", value: 111 },// { label: "测试1-1-2", value: 112 },// { label: "测试1-1-3", value: 113 },// ],// },// { label: "测试1-2", value: 12 },// { label: "测试1-3", value: 13 },// ],// },// { label: "测试2", value: 2, children: [] },],props: {checkStrictly: true, // 取消父节点与子节点的严格关联,可以任意选中任何一级作为结束lazy: true,lazyLoad: (node, resolve) => {let result = node.data;console.log("点击的节点数据", result);if (result) {if (result.level != 3) {this.getTempData(Number(result.level) + 1, result.value).then((sourceData) => {let data = [];if (sourceData && sourceData.length > 0) {data = sourceData;}resolve(data);});} else {resolve([]);}} else {}},},};},created() {},mounted() {let flag = true; // flag 控制是执行新增还是编辑if (flag) {// 是编辑this.getDetail();} else {// 是新增this.getTempData(1).then((dataLev1) => {this.options = dataLev1;});}},watch: {},computed: {},methods: {chaangeFunc() {console.log("触发了change", this.value);// 选中节点后,关闭下拉this.$refs.refHandle.dropDownVisible = false;},// mock 接口数据getTempData(level, key) {return new Promise((resolve, reject) => {let result = [];if (level == 1) {result = [{ label: "测试1", value: 1, level: 1 },{ label: "测试2", value: 2, level: 1 },];}if (level == 2) {if (key == 1) {result = [{ label: "测试1-1", value: 11, level: 2 },{ label: "测试1-2", value: 12, level: 2 },{ label: "测试1-3", value: 13, level: 2 },];}}if (level == 3) {if (key == 11) {result = [{ label: "测试1-1-1", value: 111, level: 3 },{ label: "测试1-1-2", value: 112, level: 3 },{ label: "测试1-1-3", value: 113, level: 3 },];}}setTimeout((item, index) => {console.log("级联请求到的数据", result);resolve(result);}, 1000);});},getDetail() {let detailList = [1, 11, 111]; // 模拟获取到的需要渲染的节点数据this.getTempData(1).then((dataLev1) => {this.options = dataLev1;console.log("渲染完了一级");this.options.map((itemLev1, indexLev1) => {if (itemLev1.value == detailList[0]) {console.log("匹配到一级选中内容,开始查询二级");this.getTempData(2, itemLev1.value).then((dataLev2) => {if (dataLev2 && dataLev2.length > 0) {console.log("查询到了二级数据,继续向下查询");this.$set(itemLev1, "children", dataLev2);console.log("渲染完了二级");itemLev1.children.map((itemLev2, indexLev2) => {if (itemLev2.value == detailList[1]) {console.log("匹配到二级选中内容,开始查询三级");this.getTempData(3, itemLev2.value).then((dataLev3) => {if (dataLev3 && dataLev3.length > 0) {console.log("查询到了三级数据,即最末为三级");this.$set(itemLev2, "children", dataLev3);itemLev2.children.map((itemLev3, indexLev3) => {console.log("末级添加标志位");itemLev3.leaf = "leaf";});} else {console.log("未查询到三级数据,即最末为二级");itemLev2.leaf = "leaf";}console.log("渲染完了三级");this.value = detailList;this.num += 1;});}});} else {console.log("未查询到二级数据,即最末为一级");itemLev1.leaf = "leaf";}this.value = detailList;this.num += 1;});}});});},},
};
</script>