element中el-cascader的使用
从后端拿到arr数据结构:
cityList: [
{
id: 1,
name: '北京',
child: [
id: 11,
name: '大兴区',
child: [
id: 111,
name: '亦庄'
]
]
}
]
vue文件代码
<template>
<el-cascader
:options="cityList"
:props="optionProps"
v-model="selectedOptions"
@change="handleChange">
</el-cascader>
</template>
<script>
data: {
optionProps: {
value: 'id',
label: 'name',
children: 'child'
}
}
</script>
使用el-cascader报错解决
项目中使用到了element-ui中的cascader级联选择器,组件下拉列表是动态的,根据用户选择的类型来从后台请求数据
<el-select v-model="type" @change="getCascader" placeholder="请选择类型">
<el-option
v-for="item in type"
:key="item.typeValue"
:label="item.typeName"
:value="item.typeValue"
/>
</el-select>
<el-cascader
:options="cascaderOption"
:props="props"
v-model="cascaderValue"
collapse-tags
:placeholder="请先选择类型"
/>
再根据后台获取的数据,加载级联选择器
getCascader() {
this.cascaderValue= []
getCascader(this.type).then(response => {
this.cascaderOption = response.data.data
});
}
于是就出现bug了
一、options为空的情况
场景:有的类型没有数据,这时cascader的options是[ ],下拉框是空的。
如果选择了一个类型,根据类型获取了cascader的数据,在cascader中选择了一条数据,再更换类型,没有这条数据了就会报错
[Vue warn]: Error in callback for watcher "options": "TypeError: Cannot read property 'level' of null
TypeError: Cannot read property 'level' of null
根据报错信息点进去看了一下,发现cascader有选中项的绑定值checkedValue和点击的父节点(高亮)activePath , 即便设置了this.cascaderValue= [] ,cascader中的activePath还是有值,也就是点击的父节点会被记录下来,再次加载cascader找不到就会报错。
解决:如果没有数据就将cascader设置为不可编辑
<el-cascader
:options="cascaderOption"
:props="props"
:disabled="optionsChanged"
v-model="cascaderValue"
collapse-tags
:placeholder="showPlaceholder"
/>
并且直接return,不加载下拉节点
getCascader() {
this.cascaderValue= []
getCascader(this.type).then(response => {
if(response.data.data.length === 0){
this.optionsChanged = true
this.showPlaceholder = '暂无范围'
return
}
this.cascaderOption = response.data.data
});
}
二、编辑时给cascader赋值
场景:cascader下拉节点的数据由后台提供,编辑时的显示值依然让后台提供,将后台返回的信息直接赋值给cascaderthis.type = row.type //row为后台返回的数据。
这样赋值是可以显示的,但是改变类型后,cascader的options又动态改变,这就导致了cascader的value在下拉节点中不存在,又跟一options为空的情况报了同样的错误
[Vue warn]: Error in callback for watcher "options": "TypeError: Cannot read property 'level' of null
TypeError: Cannot read property 'level' of null
刚开始以为是后台返回的数据有问题,将后台返回的数组直接写死赋值给cascader就不会报错,只要数据写死就不会报错,动态赋值就报错。
this.type = ['1','2']
真让人摸不着头脑。
解决:叫上后台一起排查后发现将返回的options中的value从string改成了int就可以了
三、点击了父节点后改变了cascader的options
场景:后面又发现了一个bug,就是点击了父节点但是并没有选中的时候,改变了类型,options也动态改变了,改变后没有这个父节点就会报错。
当然,选中了节点同样会报错,只要有activePath 就会报错。
[Vue warn]: Error in callback for watcher "options": "TypeError: Cannot read property 'level' of null
TypeError: Cannot read property 'level' of null
解决:与一options为空的bug类似,重新渲染cascader都可以解决。
改变类型,cascader的options改变后,将cascader重新渲染。
重新渲染组件的方法有两种:
- 1、给cascader设置v-if,改变类型后,赋值options前将v-if设置为true就可以重新渲染cascader,但是这样有个缺陷就是不流畅,v-if设置为false时cascader的位置会空白,影响用户体验。
- 2、给cascader设置一个key,改变类型时也改变key值,key值改变了,cascader就会重新渲染
<el-cascader
:key="isResouceShow"
:options="cascaderOption"
:props="props"
:disabled="optionsChanged"
v-model="cascaderValue"
collapse-tags
:placeholder="showPlaceholder"
/>
getCascader() {
this.cascaderValue= []
++this.isResouceShow
this.showPlaceholder = '请先选择所属范围'
getCascader(this.type).then(response => {
if(response.data.data.length === 0){
this.optionsChanged = true
this.showPlaceholder = '暂无范围'
return
}
this.cascaderOption = response.data.data
});
}
以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。