这里先描述一下出现问题过程:
1、要做数据的增删改查,在数据编辑的时候是从右侧打开抽屉中显示form表单,我将抽屉封装成了一个组件单独抽离。就需要在父组件中将 :visible.sync="dialogVisible"绑定的dialogVisible置为true,然后在抽屉事件的open中调编辑详情接口,级联组件懒加载自动执行城市联动接口。
2、再说一下懒加载中城市返显要必备的条件:组件绑定的cityList是个数组,并且里面有城市id,例如:北京市 北京城区 东城区 要想返显这个数据则绑定的数组中是[1,2,3],这样级联组件才可以用这个数据去调接口拿返显的数据
<el-cascader v-model="formObj.cityList" :props="casProps" style="width: 100%" :key="flag"></el-cascader>
3、现在出现返显的原因是:在级联组件执行调接口时候,详情接口还没有返回formObj.cityList这个数据,导致这个formObj.cityList数组是空,所以城市不能返显成功
==接下来看一下没有返显成功的原因==
lazyLoadArea(node, resolve) {
const id = node.value || 0
this.getCity(id).then((res) => {
const nodes = JSON.parse(JSON.stringify(res.data))
nodes.forEach((item) => {
if (!item.subCount) {
item['leaf'] = true
}
})
resolve(nodes)
})
}
以上代码是逻辑中要执行的懒加载方法,可以看一下关键方法resolve(nodes),是将接口返回的一级城市数据作为参数传给resolve方法去进行二级市区数据的请求,此时的接口需要传入一级选中城市的id才能获取到二级的
下面看一下源码中的这个方法是怎么执行的
通过断点方式进入: 源码中这段就是执行懒加载的核心代码: 这里说一下那部分的判断:
- 首先_this5.checkedValue是详情接口返回城市id数组[1,2,3],会判断这个属性是不是数组,如果是才会进入判断
- 遍历checkedValue数组第一个数,从dataList(这个属性是第一次城市接口返回来的一级城市数据)过滤返回符合checkedValue第一个数id的值,如果有则继续执行,没有则退出执行,这里可以看出==checkedValue==中是否有值是非常关键的
我问题出现的原因就在这里,因为接口异步和网络抖动的原因不能保证在执行这个懒加载递归的时候城市id数组是否已经被返回,所以会出现偶尔有不能返显的问题
好了,咱们问题出现原因已经找到:下面说一下解决办法
==解决办法==
watch: {
'formObj.cityList': {
deep: true,
handler(newValue, oldValue) {
this.watchIndex++
if (this.watchIndex === 1) {
this.flag = !this.flag
}
},
},
},
给组件绑定了一个key值,并且给formObj.cityList数组加了一个监听,数组改变时修改绑定key的flag值,这样完美解决问题
为什么要这么做呢?
这得说Vue的源码更新机制: vue/src/core/vdom/patch.js 这个文件中diff运算会判断这个是不是同一个节点,去进行更新这个节点 结论:所说使用监听去修改flag这个值之后,组件会重新渲染一次,这个时候数据都已经拿到了,所以就可以解决问题了