<template>
<div>
<el-cascader filterable ref="myCascader" :options="options" v-model="vop" :show-all-levels="false" collapse-tags
@change="handleChange" :props="{children: 'children',label: 'name',
value:'pkOrg', multiple: true, checkStrictly: true,
emitPath: false, expandTrigger:'click'
}" clearable>el-cascader>
div>
template>
<script>
export default {
props: {
// 级联树数据定义
options: {
type: Array,
required: true,
default: true
},
// 级联选择器一开始绑定值,需回显
updateValue: {
type: Array,
required: true,
default: true
},
// firstOrgId:Object,
},
data() {
return {
// 选中的值
vop: [],
// 临时存放的当前选中值,用于后期的点击对比,获得当前节点值
tmpVop: [],
// 临时存放的值,用于递归函数给选中值
tmp: '',
}
},
created() {
this.handleChange()
},
watch: {
/** v-model绑定得值 */
vop: {
handler(n) {
// 如果数据发生变化
if (n) {
this.$emit('childByValue', this.vop)
}
},
deep: true,
immediate: true
},
/** 如果一开始就给级联选择器赋值了 */
updateValue: {
handler(n) {
if (n) {
// 拿到父级节点的值,进行回显
this.vop = this.updateValue
this.tmpVop = this.vop
}
},
deep: true,
immediate: true
}
},
methods: {
// 选中或取消选中后的赋值
checkArr(value, options, operation) {
console.log(value, options, operation,'myCascader')
options.map((x) => {
if (value === x.pkOrg) {
// 选中value项,并循环该节点下的其他所有子节点选中
if (x.children) {
this.checkArrNull(x.children, operation)
}
} else if (x.children) {
this.checkArr(value, x.children, operation)
}
})
},
checkArrNull(options, operation) {
console.log(options, operation,"myCascader")
options.map((x) => {
// 如果有子项,则递归,没有则选中
// 选中当前节点2判断子节点,有则继续递归
if (operation === 'add') {
this.tmp = this.tmp + ',' + x.pkOrg
} else if (operation === 'sub') {
this.tmp = this.tmp.split(',')
// shanchu zhi
this.tmp = this.removeValue(x.pkOrg, this.tmp)
this.tmp = this.tmp.join(',')
}
if (x.children) {
this.checkArrNull(x.children, operation)
}
})
},
// 获得点击change事件时点击节点的值
valueChange(tmp1, tmp2,action) {
console.log(tmp1,tmp2,"myCascader")
//新数组用来接收遍历的
let newTem1 = [];
//循环
tmp1.forEach((item) => {
newTem1.push(parseInt(item))
})
//筛选出不同的数字
let difference = [];
if(action === 'add'){
// 选中
difference = tmp2.filter(x => newTem1.indexOf(x) == -1);
}else{
// 取消选中
difference = newTem1.filter(x => tmp2.indexOf(x) == -1)
}
console.log(difference,"myCascader")
return difference[0];
},
// 删除数组指定的值的元素
removeValue(v, arr) {
v = v.toString();
console.log(v,arr,"myCascader")
let index = arr.indexOf(v)
console.log(index,"myCascader")
if (index !== -1) {
arr.splice(index, 1)
}
return arr
},
// 数组去重
unique(arr) {
var arr2 = arr.sort()
var res = [arr2[0]]
for (var i = 1; i < arr2.length; i++) {
if (arr2[i] !== res[res.length - 1]) {
res.push(arr2[i])
}
}
return res
},
// 将options的value值按照value生成一组数组
optionsToarr(options) {
this.tmp = ''
options.map((x) => {
this.tmp = this.tmp + x.pkOrg + ','
if (x.children) {
this.optionsToarrChild(x.children)
}
})
},
optionsToarrChild(options) {
options.map((x) => {
this.tmp = this.tmp + x.pkOrg + ','
if (x.children) {
this.optionsToarrChild(x.children)
}
})
},
// change事件
handleChange(value) {
// 获得点击变化时的值,然后判断是加值还是减值。根据值去递归
let valueCh = ''
// 操作是选中还是取消
let action = ''
// 对比获得是选中还是取消操作
if ((this.vop).length > 0) {
console.log(this.tmpVop,this.vop,"myCascader")
if ((this.tmpVop).length > (this.vop).length) {
valueCh = this.valueChange(this.tmpVop, this.vop,'sub')
action = 'sub'
} else {
valueCh = this.valueChange(this.tmpVop, this.vop,'add')
action = 'add'
}
}
if (valueCh) {
console.log(this.options,"myCascader")
this.tmp = this.vop.join(',')
this.checkArr(valueCh, this.options, action)
// 去重
this.vop = this.unique(this.tmp.split(','))
}
// 获得options的value值一维数组,用于排序对照
this.optionsToarr(this.options)
if (this.tmp.substring(this.tmp.length - 1) === ',') {
this.tmp = this.tmp.substring(0, this.tmp.length - 1)
}
this.tmp = this.tmp.split(',')
// 排序
this.vop.sort((prev, next) => {
return this.tmp.indexOf(prev) - this.tmp.indexOf(next)
})
this.tmpVop = this.vop
}
},
created() {
// 创建时默认给tmpVop赋值
this.tmpVop = this.vop
}
}
script>
<style scoped="scoped" lang="scss">
/deep/ .el-cascader .el-cascader__tags .el-cascader__search-input{
display: none !important;
}
style>
组件用法:
<-- updateValue : 当前选中的值 childByValue : 数据发生改变 子传父事件 options : 组织树 -->
<myCascader v-model="updateVaule" :updateValue="updateVaule" class="sszz_cascader"
v-on:childByValue="childByValue" :options="orgs">
myCascader>
`