背景
某些情况下使用级联器时需要将已有的数据加载到级联器选择列表中,此时使用懒加载会使多级选项丢失,如图:
-
懒加载前
-
懒加载后
解决方法
- 初始化级联器选项(options)时,将已选列表加入选项。此方法仅限于已选列表数据均为最后一层的情况。否则也会触发懒加载造成数据丢失。
// Mixin 文件
// Mixins.js
export const Mixins = {
data() {
return {};
},
methods: {
/**
* 通过路径字符串列表生成级联器选项
* @param origin 原始路径字符串列表
* @returns {({children: *, label: *, value: *}|{label: *, value: *})[]}
*/
createCascadorOptionsFromArray(origin) {
let container = {};
origin.map(path => {
this.genPathTier(container, path.split('/'));
})
return Object.entries(container).map(
([key, val]) => this.createCascadorOptionsFromPathArray(key, val)
);
},
/**
* 将二维路径列表合并为树形结构
* 例:['parent/child_st', 'parent/child_nd'] => [['parent', 'child_st'], ['parent', 'child_nd']] => {'parent': ['child_st', 'child_nd']}
* @param container 容器,用以存放树形结构数据
* @param pathArray 分离路径字符串得到的路径列表
*/
genPathTier(container, pathArray) {
if (pathArray.length > 1) {
let parent = pathArray.shift();
if (!container[parent]) {
container[parent] = {};
}
this.genPathTier(container[parent], pathArray);
} else {
container[pathArray.shift()] = [];
}
},
/**
* 通过生成的路径树形结构数据获得级联器选项
* @param cur 当前路径
* @param childrenTier 当前路径的子级
* @returns {{children: ({children: *, label: *, value: *}|{label: *, value: *})[], label, value}|{label, value}}
*/
createCascadorOptionsFromPathArray(cur, childrenTier) {
if (Object.keys(childrenTier).length) {
return {
value: cur, label: cur,
children: Object.entries(childrenTier).map(
([key, val]) => this.createCascadorOptionsFromPathArray(key, val)
)
};
} else {
return {value: cur, label: cur}
}
}
},
}
import {Mixins} from "./Mixins";
mixins: [Mixins],
methods: {
genCascaderOptions(){
CusApi.getPathTree().then(res => {
// 通过 API 获取第一层并与已选列表一起传入自定义方法生成级联器选项
this.PathCascaderOptions = this.createCascadorOptionsFromArray(
[...res.data.TreeResponse, ...this.formData.path || []]
);
})
}
}
- 懒加载前保存已选列表,懒加载后重新渲染。
gitbasePathCascaderProps: {
lazy: true,
lazyLoad: async (node, resolve) => {
const {path} = node;
// 懒加载前保存已选列表,用以加载后重新回显。
let originSelectPath = [...this.formData.path];
// 子级节点有值则跳过请求。
if ((node.children || []).length) {
resolve();
} else {
await CusApi.getPathTree().then(res => {
// 若请求失败或已有子级,则不进行任何刷新。
if (res.status === 200) {
// 通过调用resolve将子节点数据返回,通知组件数据加载完成
resolve(res.data.Response.map(path => {
return {value: path, label: path, children: []};
}));
} else {
resolve();
}
});
}
// 重新回显已选列表,必须在下一次渲染后执行,否则数据的更新会在渲染前,导致级联器无法成功监听数据变动。
this.$nextTick(() => {
// 一定要将级联器数据置空,否则可能不会触发重载。
this.formData.path = [];
this.formData.path = originSelectPath;
});
},
},