element-ui的多级选择器cascader维护的是一个数组, 但在实际需求中我们往往只要维护某个子项的id即可, 如部门、组织等. 在提交表单时我们把子项id post给后台, 在表单回显时需要根据子项id找到该子项的所有上级进行回显。 这时cascader将无法胜任我们的需求,
解决办法: 在cascader的基础上二次封装一个公共组件
SelectTree.vue (代码仅供参考)
<template>
<el-cascader
style="width:100%"
:options="options"
v-model="valueArr"
@change="change"
:props="treeProps"
:clearable="clearable"
></el-cascader>
</template>
<script>
import { myDeptTree } from '@/api/userInfo'
export default {
name: '',
props: {
value: {},
// 是否多选
multiple: {
type: Boolean,
default: () => false,
},
// 是否可选任意一级
checkStrictly: {
type: Boolean,
default: () => false,
},
// 是否可清除
clearable: {
type: Boolean,
default: () => true,
},
// 类型
type: {
type: String,
default: () => '',
},
},
components: {},
data() {
return {
valueArr: [],
options: [],
treeProps: {
multiple: this.multiple,
checkStrictly: this.checkStrictly,
value: 'id',
label: 'categoryName',
children: 'children',
},
}
},
watch: {
value: {
handler() {
this.initData()
},
deep: true,
},
},
methods: {
initData() {
if (!this.valueArr.length) {
let val = this.getTreeDeepArr(this.value, this.options)
this.valueArr = val
}
if (!this.value) {
this.valueArr = []
}
},
change(val) {
this.$emit('input', val[val.length - 1])
},
getTreeDeepArr(key, treeData) {
let childrenKey = 'children'
if (this.type === 'organization') {
childrenKey = 'childDeptList'
}
let arr = [] // 在递归时操作的数组
let returnArr = [] // 存放结果的数组
let depth = 0 // 定义全局层级
// 定义递归函数
function childrenEach(childrenData, depthN) {
for (var j = 0; j < childrenData.length; j++) {
depth = depthN // 将执行的层级赋值 到 全局层级
arr[depthN] = childrenData[j].id
if (childrenData[j].id == key) {
// returnArr = arr; // 原写法不行, 因 此赋值存在指针关系
returnArr = arr.slice(0, depthN + 1) //将目前匹配的数组,截断并保存到结果数组,
break
} else {
if (childrenData[j][childrenKey]) {
depth++
childrenEach(childrenData[j][childrenKey], depth)
}
}
}
return returnArr
}
return childrenEach(treeData, depth)
},
initOptions() {
switch (this.type) {
case 'organization':
this.organization()
break
default:
break
}
},
async organization() {
let res = await myDeptTree()
this.treeProps.label = 'deptName'
this.treeProps.children = 'childDeptList'
this.options = res
this.initData()
},
},
mounted() {
this.initOptions()
},
}
</script>
页面中使用
<SelectTree v-model="searchData.deptId" type="organization" checkStrictly />