el已于2.9.2版本更新懒加载方法 详细请前往官网查看
2020年1月10日 更新
突然看到这个代码 就继续研究了一下 添加了懒加载时可以只选最后一级 就是没有children的那一级
首先el-cascader中change-on-select是控制是否允许选择任意层级的
当值为true时 每次点击item都会触发change事件 但不会触发active-item-change事件
当值为false时 每次点击item都会触发active-item-change事件 但不会触发change事件
于是…当组件化时不确定change-on-select到底传啥时,我就同时监听这俩事件
具体的话 可以看下面的代码 注释也更新了
问题描述
这个功能主要的难点在于多级时,动态加载出的数据该塞到哪个节点下,下面的内容主要就是解决这个问题的。
el-cascader级联组件动态加载数据
首先理一下思路,假设点击第一层某个选择,通过change事件获取值,并请求,返回的数据放到第一层哪一条?
再看一下elementUI官网对于prop中的value介绍
也就是说通过change获取到的value是string类型,如果获取到的是个对象,那么就可以把当前数据的索引放在当前数据的某个键里,再通过索引将后台返回的数据放入选项里.
总结下来,就剩一个问题了,就是如何获取一整条对象,而不是一个字符串,只需要把当前数据通过JSON.stringify()转换成字符串,选中时,再将字符串转换成对象就行了,具体可看一下代码:
<template>
<div id="zoning">
<!--change-on-select是否允许选择任意一级的选项 必须为true 否则触发不了change事件,因为我的首项带child 算是父级-->
<!--如果change-on-select为false @change不会触发 但会触发active-item-change事件-->
<el-cascader
:options="options"
:clearable="true"
size="mini"
ref="cascader"
@change="handleItemChange"
@active-item-change="handleItemChange"
:change-on-select="changeOnSelect"
:props="props"
></el-cascader>
</div>
</template>
<script>
export default {
components: {},
filters: {},
props:{
// 如果该值为false 则只能选择最后一级
// 如果该值为true 则可以选择任意层级
changeOnSelect:{
default:false
}
},
data () {
return {
options: [],
props: {
value: 'main',
// 显示的文字字段名
label: 'label',
// 子层级字段名
children: 'child'
}
}
},
methods: {
/**初始化
* */
getZoning () {
let self = this;
// 发送请求
self.$backend.request(self.$api.user.getZoning, {id: 0}).then(res => {
self.options = res.list
self.options.map((item, index) => {
for (let k in item) {
if (!item[k]) {
delete item[k]
}
}
// 先让数据变成父级
item.child = []
// 手动创建字段表明当前索引 假设arrIndex值为'1-2-3' 即为options[1].child[2].child[3]
item.arrIndex = index + ''
// 将当前数据转成字符串放入对象里 当做value值
item.main = JSON.stringify(item)
})
})
},
handleItemChange (val) {
// 因为允许选择任意级,所以在向下选择时,会出现选择多个的情况,造成选中的合并成了一个数组,我这里只让他选择到第三层,页面上最多只会出现选择三个,如果超出了,直接return出去 不需要再动态加载下去了
if (val.length > 2) return
//每选中一个选项,相当于将本条数据push到val里,所以索引为val.length - 1的那一项必然是当前点击的那一项
val = JSON.parse(val[val.length - 1])
//发送请求
this.$backend.request(this.$api.user.getZoning, {id: val.roid}).then(res => {
let data = res.list
//arrIndex是手动塞进去的索引
let arrIndex = val.arrIndex
data.map((item, index) => {
// 手动创建字段表明当前索引 假设arrIndex值为'1-2-3' 即为options[1].child[2].child[3]
item.arrIndex = arrIndex + '-' + index
// 将当前数据转成字符串放入对象里 当做value值
item.main = JSON.stringify(item)
// 判断是否是第三层及以上
if (item.arrIndex.split('-').length < 3) {
item.child = []
}
})
// 根据父元素的arrIndex判断塞到哪个父元素下
arrIndex = arrIndex.split('-')
// 首项键不是child 和for循环里区别开
let a = this.options[arrIndex[0]]
for (let i = 1; i < arrIndex.length; i++) {
a = a['child'][arrIndex[i]]
}
this.$delete(a, 'child');
this.$set(a, 'child', data)
})
}
},
mounted () {
this.getZoning()
},
}
</script>
<style scoped>
</style>