一、效果图
二,主要代码
<el-cascader
v-model="searchForm.manualTagIds"
:options="personOptions"
@change="selectHandle"
:props="{
label: 'name',
value: 'id',
multiple: true,
children: 'childTags',
}"
collapse-tags
clearable
:style="
'width:' +
this.$store.state.FormInputWidth.elFormItemWidth -
25 +
'px'
"
size="small"
popper-class="TagIdsClass"
></el-cascader>
lastSelectedList: [], // 上次选中的数据
oneDimensionalList: [], // 源数据平铺成一级节点
this.personOptions.unshift({ id: '全选', name: '全选' })
getTreeList(list) {
let _this = this
for (let i = 0; i < list.length; i++) {
let a = list[i]
if (a.name !== '全选') {
this.oneDimensionalList.push(list[i])
}
if (a.childTags && a.childTags.length > 0) {
let res = _this.getTreeList(a.childTags)
if (res) {
return res
}
}
}
},
judgetAllSelected(node) {
// 判断是否是全选,也就是看已选择的选中中包不包含"全选"
let isAllSelected = false
for (let i = 0; i < node.length; i++) {
if (node[i][0] === '全选') {
isAllSelected = true
break
}
}
return isAllSelected
},
loopSelectData(list, parentNode = []) {
list.length > 0 &&
list.forEach(e => {
let pNode = [...parentNode] // 注意这里必须是深拷贝,否则会由于引用类型赋值的是地址(指针),导致parentNode在pNode更新时,同时被更新
if (e.childTags && e.childTags.length > 0) {
pNode.push(e.id) // 1 11
this.loopSelectData(e.childTags, pNode)
} else {
if (parentNode.length > 0) {
this.searchForm.manualTagIds.push([...parentNode, e.id])
} else {
this.searchForm.manualTagIds.push([e.id])
}
}
})
},
checkIsAddAllSelected() {
//这里你要判断好你的dom是否正确
let label1 = document
.querySelectorAll('.el-cascader-panel')[1]
.querySelector('.el-cascader-menu__wrap')
.querySelectorAll('li')[0]
.querySelectorAll('label')[0]
let span1 = document
.querySelectorAll('.el-cascader-panel')[1]
.querySelector('.el-cascader-menu__wrap')
.querySelectorAll('li')[0]
.querySelectorAll('label')[0]
.querySelectorAll('span')[0]
// 获取所有的数据
let list = this.personOptions // 原始数据列表
if (this.oneDimensionalList.length === 0) {
this.getTreeList(list) // 把所有的父子级平铺成一个一级列表
}
let origin = [...this.oneDimensionalList].filter(item => !item.childTags) //获取所有的叶子节点
let nowList = [...this.searchForm.manualTagIds].filter(item => item[0] !== '全选')
// 半选时, 如果有之前选过全选,要把全选过滤掉
if (origin.length > nowList.length && nowList.length != 0) {
this.searchForm.manualTagIds = this.searchForm.manualTagIds.filter(
item => item[0] !== '全选'
)
//设置半选样式,setTimeout可以解决样式渲染不上的问题
setTimeout(function () {
label1.className = 'el-checkbox'
span1.className = 'el-checkbox__input is-indeterminate'
}, 1)
} else if (nowList.length == 0) {
//不选时, 如果有之前选过全选,要把全选过滤掉
this.searchForm.manualTagIds = this.searchForm.manualTagIds.filter(
item => item[0] !== '全选'
)
label1.className = 'el-checkbox'
span1.className = 'el-checkbox__input'
} else {
// 当所有的数据都选择时, 要自动把全选勾选上 最后这种是:origin.length == nowList.length
if (
this.searchForm.manualTagIds[0] &&
this.searchForm.manualTagIds[0][0] !== '全选'
) {
this.searchForm.manualTagIds = [['全选'], ...this.searchForm.manualTagIds]
label1.className = 'el-checkbox'
span1.className = 'el-checkbox__input is-checked'
}
}
},
// 选择级联选择器
async selectHandle(e = []) {
this.searchForm.manualTagIds = []
// 选中的数据格式: [['全选'], [1, 2], [1, 3], [1, 4],[5, 6], [5, 7, 8],5, 7, 9],[10]]
let list = this.personOptions //级联选择器的数据
let current = [] // 获取当前选中的哪个数据,因为element文档中没有获取当前选中数据的方法,只能通过上次选中的数据和这次选中的数据进行比较来获取
// 选中的所有数据list和上一次选中的list进行比较
if (e.length >= this.lastSelectedList.length) {
let keys = this.lastSelectedList.map(item => JSON.stringify(item))
current = e.filter(item => !keys.includes(JSON.stringify(item)))
} else {
// 取消选中
let keys = e.map(item => JSON.stringify(item))
current = this.lastSelectedList.filter(item => !keys.includes(JSON.stringify(item)))
}
// 根据element的选中数据格式, 每一个选项都是一个列表, 列表第一项为父级value, 第二项为选中的子级value, ...以此类推
const currentValue = current.length > 0 ? current[0][0] || '' : ''
if (currentValue === '全选') {
if (this.judgetAllSelected(e)) {
this.loopSelectData(list) //获取全选时回显的数据
} else {
this.searchForm.manualTagIds = [] //不选
}
} else {
this.searchForm.manualTagIds = e //半选
}
// 根据当前选择的数据(不包括全选)和全选时所有的数据--进行对比
this.checkIsAddAllSelected()
this.lastSelectedList = this.searchForm.manualTagIds // 保存上一次的选择结果
},
链接: https://blog.csdn.net/qq_32166301/article/details/130198310