(vue)el-cascader级联选择器按勾选的顺序传值,摆脱层级约束
-
需求:按勾选的顺序给后端传值
-
难点:在 Element UI 的 el-cascader 组件中,默认的行为是根据数据的层级结构来显示选项,用户的选择也会基于这种层级结构,el-cascader 本身并不直接支持自定义的显示顺序。
效果:
实现:
// html
<el-cascader
v-model="selectedOptions"
:options="options"
:props="props"
clearable>
</el-cascader>
// js
export default {
data(){
return {
selectedOptions:[],// 绑定的数组
sortSelectedOptions:[],// 排好序的数组
// props: { multiple: true },// 原始获取到的value是数字,不方便对比
props: { multiple: true, value: 'label', label: 'label' },// 指定value值取label
options: [{
value: 1,
label: '东南',
children: [{
value: 2,
label: '上海',
children: [
{ value: 3, label: '普陀' },
{ value: 4, label: '黄埔' },
{ value: 5, label: '徐汇' }
]
}, {
value: 7,
label: '江苏',
children: [
{ value: 8, label: '南京' },
{ value: 9, label: '苏州' },
{ value: 10, label: '无锡' }
]
}, {
value: 12,
label: '浙江',
children: [
{ value: 13, label: '杭州' },
{ value: 14, label: '宁波' },
{ value: 15, label: '嘉兴' }
]
}]
}, {
value: 17,
label: '西北',
children: [{
value: 18,
label: '陕西',
children: [
{ value: 19, label: '西安' },
{ value: 20, label: '延安' }
]
}, {
value: 21,
label: '新疆维吾尔族自治区',
children: [
{ value: 22, label: '乌鲁木齐' },
{ value: 23, label: '克拉玛依' }
]
}]
}]
}
}
},
// 监听绑定数组
watch:{
selectedOptions: {
handler(newVal, oldValue) {
if (newVal.length > oldValue.length) {
// 找到新增的项
const newItems = this.findNewItems(oldValue, newVal)
// 添加到排序数组中
this.sortSelectedOptions.push(...newItems)
}
if (newVal.length < oldValue.length) {
// 找到删除的项
const newItems = this.findNewItems(newVal, oldValue)
// 从排序数组中过滤掉被删除的项
this.sortSelectedOptions = this.sortSelectedOptions.filter(item => {
return !newItems.map(e => JSON.stringify(e)).includes(JSON.stringify(item))
})
}
console.log('this.sortSelectedOptions', this.sortSelectedOptions)
},
deep: true
}
},
methods:{
findNewItems(oldList, newList) {
// 创建一个映射表来快速检查旧列表中的项
const oldItemsMap = new Map()
for (const item of oldList) {
// 使用JSON.stringify作为唯一标识符(注意:如果子数组顺序重要且可能不同,这种方法可能不适用)
oldItemsMap.set(JSON.stringify(item), true)
}
// 遍历新列表,检查哪些项不在旧列表中
const newItems = []
for (const item of newList) {
if (!oldItemsMap.has(JSON.stringify(item))) {
newItems.push(item)
}
}
return newItems
},
}