关于el-cascader再次加载时,懒加载不回显的问题
前情提要
在项目中使用form表单,提交地区code编码
该编码的节点使用el-cascader的懒加载,正常表单的回显完全没有问题
问题详情
第一次,加载 [‘3501′,’350101’] 会回显数据
第二次,加载 [‘3501′,’350101′,’35010102′,’3501010202’] 时,text不回显
即层数更多时不回显
代码如下,没有问题
<template>
<el-form-item label="地区" prop="dqs">
<el-cascader
v-model="dqs"
:options="regions"
:props="{ checkStrictly: true, value: 'code', label: 'name', leaf: 'hasChildren', lazy: true, lazyLoad: lazyLoad }"
style="width: 447px"
@change="regionChange"
:disabled="IsSelfDisabled"
placeholder="地区"
clearable>
</el-cascader>
</el-form-item>
</template>
<script>
export default {
data() {
return {
regions: [{
value: 'code',
label: '',
children: [],
},{xxx},{xxx}],
dqs: ['3501','350101']
}
},
methods: {
lazyLoad(node, resolve) {
if (node.value && node.value.length === 12) {
resolve()
return
}
setTimeout(() => {
POST({ code: node.value }).then(res => {
res.data.forEach(item => {
item.hasChildren = !item.hasChildren
})
resolve(res.data)
})
}, 100)
}
}
</script>
解决过程
断点查看时发现,二次加载的时候,只回调了一次lazyLoad
明显不对,遂跟进js调用链
lazyLoad(cascader-panel)->lazyLoad(vue)->lazyLoad(cascader-panel)(resolve)
即没有重复调用lazyLoad的原因应该在cascader-panel的lazyLoad里
查看js代码,下断点
//node_modules/element-ui/lib/cascader-panel.js
lazyLoad: function lazyLoad(node, onFullfiled) {
var _this5 = this;
var config = this.config;
if (!node) {
node = node || { root: true, level: 0 };
this.store = new src_store([], config);
this.menus = [this.store.getNodes()];
}
node.loading = true;
var resolve = function resolve(dataList) {
var parent = node.root ? null : node;
dataList && dataList.length && _this5.store.appendNodes(dataList, parent);
node.loading = false;
node.loaded = true;
// dispose default value on lazy load mode
if (Array.isArray(_this5.checkedValue)) {
var nodeValue = _this5.checkedValue[_this5.loadCount++];
var valueKey = _this5.config.value;
var leafKey = _this5.config.leaf;
if (Array.isArray(dataList) && dataList.filter(function (item) {
return item[valueKey] === nodeValue;
}).length > 0) {
var checkedNode = _this5.store.getNodeByValue(nodeValue);
if (!checkedNode.data[leafKey]) {
_this5.lazyLoad(checkedNode, function () {
_this5.handleExpand(checkedNode);
});
}
if (_this5.loadCount === _this5.checkedValue.length) {
//此处为 回显文本赋值 的函数
_this5.$parent.computePresentText();
}
}
}
onFullfiled && onFullfiled(dataList);
};
config.lazyLoad(node, resolve);
}
分别对20,25,38,45行断点,发现在二次调用时,25行的
ataList.filter(function (item) {
return item[valueKey] === nodeValue;
}
返回了一个空数组 []
(即当前的节点数据中并不包含nodeValue的值)
导致二次调用并没有在28~39行内被断下,而直接返回,也不触发下一次懒加载
控制台输出发现
nodeValue = '3501010202'
item['code'] = '3501'
就很离谱,明明传的 checkedValue 是 ['3501','350101','35010102','3501010202']
这么长的数据,他应该从第一个节点遍历的,为啥跑到了第四个
查看第21行的赋值语句发现 var nodeValue = _this5.checkedValue[_this5.loadCount++];
_this5.loadCount
的值在20行的时候就已经是3了
而且这个值只在该函数调用,在data中初始化为0
这下就明白了,上一次使用 el-cascader
的数据没有被销毁,而是留到了这次渲染上了
解决方案
在新起的form 或 form提交后 销毁 el-cascader
即可
<template>
<el-form-item label="地区" prop="dqs">
<el-cascader
v-if="dqs.length" //添加此处,通过表单清空数据,根据v-if特性,来销毁el-cascader组建,达成重置loadCount的操作
v-model="dqs"
:options="regions"
:props="{ checkStrictly: true, value: 'code', label: 'name', leaf: 'hasChildren', lazy: true, lazyLoad: lazyLoad }"
style="width: 447px"
@change="regionChange"
:disabled="IsSelfDisabled"
placeholder="地区"
clearable>
</el-cascader>
</el-form-item>
</template>
总结
可以归咎为组件的数据回收问题,不过也惊醒我们一些懒加载的组件还是勤销毁比较重要