el-cascader多选懒加载回写

问题描述:

el-cascader组件在多选懒加载模式下回写不成功

在这里插入图片描述


原因分析:

el-cascader组件下拉框选项未加载出来导致的value无法回写。(经试验发现,el-cascader组件单选模式下,只要将value数据结构转成组件接收的结构即可回写成功,懒加载的回调函数会自动触发执行。但是多选模式下,即使将value数据结构转成和组件接收的二维数组结构一样,也无法自动触发懒加载回调将下拉框选项加载出来。)

解决方案:

一般懒加载的级联只需要在props属性中定义lazyLoad函数加载动态数据,但是多选的成功回写还需要在组件中定义options属性并进行递归赋值!很重要!!!如果你也是级联多选懒加载模式下回写不成功一定试试这个方法!

下面贴代码说明options属性如何赋值。

代码:

1. 模板代码片

<el-cascader
	ref="cascader"
	v-model="form.dict"
	v-loading="loading"
	:props="props"
	:options="cascaderOptions"
	@change="handleChange"
/>

属性说明:
v-model:选中项绑定值
props:配置选项
options:可选项数据源
@change:当选中节点变化时触发

2. props配置代码片

props: {
	value: 'code',
	label: 'name',
	checkStrictly: true, // 父子节点不关联
	multiple: true, // 多选
	lazy: true, // 懒加载
	lazyLoad: async(node, resolve) => {
		return this.getDict(node, resolve)
	}
}

3. 获取数据接口代码片

async getDict(node, resolve) {
	const {level, children} = node
	let params = { dmId: this.currentId }
	if (level > 0) {
		params = {
          dmId: this.currentId ,
          parentCode: node.data.code
        }
	}
	const { code, data } = await getDictList(params)
	if (code !== '200') return this.$message.warning(data.error)
	if (children && children.length) return resolve([]) // 解决重复数据问题
	resolve(data, resolve)
},

以上代码可以实现新增级联数据成功,但是编辑这条数据的时候,是无法回写展示的,所以在编辑数据时,需要递归调用数据接口获取级联下拉框选项

4. options赋值代码片

watch: {
    editRow: {
      async handler(val) {
        this.currentId = val.id
        this.form = {
          ...this.$options.data().form,
          ...val
        }
        this.$nextTick(() => {
          this.initOptions() // 初始化级联下拉选,实现回写
        })
      }
    }
},

// 初始化option
async initOptions() {
	this.loading= true
	this.cascaderOptions = []
	const params = { dmId: this.currentId }
	const { code, data } = await getDictList(params)
	if (code !== '200') return this.$message.warning(data.error)
	if (data.length) this.cascaderOptions = await this.loadOptions(data || [])
	this.loading= false
},

// 递归加载子项目
async loadOptions(dict) {
	const array = []
	for (let i = 0; i < dict.length; i++) {
        const params = {
          dmId: this.currentId,
          parentCode: dict[i].code
        }
        const { code, data } = await getDictList(params)
        if (code !== '200') return this.$message.warning(data.error)
        dict[i].children = await this.loadOptions(data)
        array.push(dict[i])
      }
	return array
},

注意点及总结:

1. 递归加载options数据时,编辑数据成功回写,但是再次点击父节点,会手动触发回调请求数据接口,导致下级出现重复数据。
在这里插入图片描述

在懒加载回调函数中,加入这句 if (children && children.length) return resolve([]) 即可解决出现重复数据的问题。

2. 级联的lazyLoad函数触发的时机是该级联输入框渲染到页面时,因此,如果级联输入框是通过其他组件联动展示的,可以通过将其options置空来触发lazyLoad函数执行。

changeType(val) {
	this.currentId = val
	this.cascaderOptions = [] // 置空触发lazyLoad函数
},

3. 由于产品要求该级联选择可以任意选择某个节点,所以我将checkStrictly属性设置成父子节点不关联,这样父节点和子节点都是可以被勾选的。但是产品又要求勾选子节点时,就不要对应的父节点了,所以还需要写一个过滤父节点数据的算法,详情可以参考我的下一篇文章: el-cascader多选过滤掉已选节点的父节点.。

结果展示:

在这里插入图片描述
写在最后: 使用options属性虽然解决了多选、懒加载模式下级联下拉框的回写问题,但是初始化递归赋值的操作会造成多次接口请求,会导致级联框渲染初始值的时候很慢,尤其是节点多的情况下。目前我是递归请求上级返回结果的所有子节点,可以优化成递归请求选中节点的数据。如果有更好的方法欢迎分享。

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值