期待需求:
1.el-cascader下拉存在多选
2.父子选项不关联
3.el-cascader支持模糊查询
4.所有的多级选项,同一条链路上一次性只保证一个点选,同层级可以多选
实现效果
代码描述
<template>
<el-cascader
v-else-if="item.type === 'Cascader'"
ref="cascaderRef"
:key="item.key"
v-model="useData.initData[item.key]"
:class="item.class"
:options="item.options"
:append-to-body="item.appendbody"
:filterable="item.filterable"
:props="dealProp(item)"
collapse-tags
:clearable="item.clearable"
popper-class="popper"
@change="onCascader(useData.initData[item.key], item, useData.initData)"
>
</el-cascader>
<template>
<script>
// label --- 名称
// key --- 双向绑定
// type --- 类型 DatePicker 时间 Select 下拉 Cascader 级联 Input 输入框
// rowId --- 第几行
// options --- 数据
// multiple --- 是否多选
// filterable --- 是否可以输入
// clearable --- 是否可以清除
// allRow -- form-item是否占一整行
// remote -- select是否使用远程搜索
// reserveKeyword -- select是否是否保留搜索关键词
// optionsHasSelectAll -- select是否有全选项
// checked -- select有全选功能时 对应的是否全选标识
// filterMethod -- select是否使用自定义搜索,select有全选时建议使用
methods:{
dealProp(item) {
return {
emitPath: true,
checkStrictly: true,
multiple: item.multiple,
expandTrigger: 'hover',
value: 'code',
label: 'name',
children: 'childrenList'
}
},
onCascader(model, item, initData) {
let modelAll = JSON.parse(JSON.stringify(model))
let filtraArr = null
// 1、树结构扁平化处理数组放到vuex
this.$store.commit('cascaderData', this.treeArr(item.options))
// 2、记录点击选中与上一次得数据
if (this.modelData.length === 0) {
this.modelData = [...model]
} else {
this.modelList = [...this.modelData]
this.modelData = [...model]
}
// 3、过滤出当前选中得数据(判断选中数据大于等2是且记录数据不为0,并且选中数据大于记录数据)
if (this.modelData.length >= 2 && this.modelList.length !== 0) {
if (this.modelData.length > this.modelList.length) {
filtraArr = this.filtrationArr(this.modelData, this.modelList)
}
}
// 4、根据选中得值跟 扁平化数据对比
if (filtraArr !== undefined && filtraArr !== null) {
let arr = filtraArr[0] // 选中当前code
let flatData = this.$store.state.user.cascaderData // 扁平数据
let currentValue = arr[arr.length - 1]
let currentNode = flatData.filter(item => item.code === currentValue)[0]
let parent = flatData.filter(item => item.code === currentNode.parentCode)[0]
let count = 1
const deleteCodes = []
if (parent !== undefined) {
deleteCodes.push(parent.code)
// 往上寻找
while (parent.level !== '1' && count < 10) {
parent = flatData.filter(item => item.code === parent.parentCode)[0]
deleteCodes.push(parent.code)
count++
}
}
// 往下寻找
let childrenNodes = flatData.filter(item => item.parentCode === currentValue)
let childrenCodes = []
childrenNodes.forEach(item => {
childrenCodes.push(item.code)
})
while (childrenCodes.length > 0) {
const code = childrenCodes.shift()
deleteCodes.push(code)
const children = flatData.filter(item => item.parentCode === code)
if (children.length > 0) {
children.forEach(item => {
childrenCodes.push(item.code)
})
}
}
const modelArr = []
modelAll.forEach(item => {
let deleteModelCode = item[item.length - 1]
let deleteState = deleteCodes.indexOf(deleteModelCode)
if (deleteState === -1) {
if (JSON.stringify(arr) === JSON.stringify(item)) {
modelArr.unshift(item)
} else {
modelArr.push(item)
}
}
})
// 拿到当前值,进行修改
let index = this.returnCurrentPicker(this.$refs.cascaderRef, item.key)
this.$nextTick(() => {
this.$refs.cascaderRef[index].checkedValue = [...modelArr]
})
}
},
}
</scrit>
分析:
提示:这样写固然没问题,会存在一个弊端,毕竟将单选得逻辑融合多选,视觉效果可能存在不合理跳转。滚动条回归至顶部。