欢迎光临
我们一直在努力

Cascader 级联选择器 一级多选 二级单选

1、需求

需要一个选择器,第一级多选,第二级单选。
于是找到了Element UI的Cascader 级联选择器,该控件唯一不满足的是开启多选后,二级也是多选,所以只需要在change事件触发时,判断同一组内是否选择了2个选项,只保留最新的选择项即可。

完整代码放在最后,可直接运行。

2、基础设置

  • 设置为支持多选、父子节点设置为不关联。
    props: { multiple: true, checkStrictly: true }
  • selectData用于绑定数据。
  • selectDataOld用于保存上一次最新的结果,用来判断和本次选择结果的差异。

3、handle事件处理

入参val判断

步骤1:过滤有效二级选项

步骤2:分组统计(同一级节点下选择项的数量)

步骤3:计算最终要保留的选项

步骤4:为selectData、selectDataOld赋值

⚠️步骤3当时遇到了一个坑。某一组有2个选项时,将val与selectDataOld比较,移除旧选项,保留新选项,然后将这一组的结果加到finalValues中。一开始使用了finalValues.push(newItem),发现每次处理过重复选项之后,控件都会默认跳到第一组选项,这个用户体验极差。
经过研究,发现控件会默认打开的数组第一个对象的面板,所以使用finalValues.unshift(newItem)将当前操作的对象插入到数组首位即可。

<!DOCTYPE html>
<html lang="zh-CN">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Element UI 控件测试页</title>
<!– 引入Element UI样式 –>
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<!– 引入Vue2 –>
<script src="https://cdn.jsdelivr.net/npm/vue@2.7.14/dist/vue.js"></script>
<!– 引入Element UI组件库 –>
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
<style>
/* 简单的页面样式,让布局更清晰 */
body {
margin: 0;
padding: 20px;
background-color: #f5f5f5;
}
</style>
</head>

<body>
<div id="app">
<el-cascader ref="cascaderRef" :options="options" :props="props" clearable @change="handle" v-model="selectData"
style="width: 100%;"></el-cascader>
</div>

<script>
new Vue({
el: '#app',
data() {
return {
selectData: [],
props: { multiple: true, checkStrictly: true },
selectDataOld: [],
options: [{
value: "东南value",
label: '东南',
disabled: true,
children: [{
value: "上海value",
label: '上海'
}, {
value: '江苏value',
label: '江苏'
}, {
value: '浙江value',
label: '浙江'
}]
}, {
value: '西北value',
label: '西北',
disabled: true,
children: [{
value: '陕西value',
label: '陕西'
}, {
value: '新疆维吾尔族自治区value',
label: '新疆维吾尔族自治区'
}]
}, {
value: 'aaaavalue',
label: 'aaaa',
disabled: true,
children: [{
value: 'bbbvalue',
label: 'bbb'
}, {
value: 'ccccvalue',
label: 'cccc'
}]
}]
}
},
methods: {
handle(val) {
//debugger;
if (!val || val.length === 0) {
this.selectData = [];
this.selectDataOld = [];
return;
}

// 步骤1:过滤有效二级选项
const validVals = val.filter(item => item.length === 2);

// 步骤2:分组统计(同一一级节点下选2个时触发替换)
const groupCount = {};
const groupItems = {};
validVals.forEach(item => {
const firstKey = item[0];
groupCount[firstKey] = (groupCount[firstKey] || 0) + 1;
if (!groupItems[firstKey]) groupItems[firstKey] = [];
groupItems[firstKey].push(item);
});

// 找到重复分组(同一一级节点选了2个)
const duplicateKey = Object.keys(groupCount).find(key => groupCount[key] === 2);
let finalValues;

if (duplicateKey) {
// 步骤3:计算最终要保留的选项
const oldItem = this.selectDataOld.find(item => item[0] === duplicateKey);
const currentItems = groupItems[duplicateKey];
let newItem = null;
if (oldItem) {
newItem = currentItems.find(item => JSON.stringify(item) !== JSON.stringify(oldItem));
} else {
newItem = currentItems[currentItems.length – 1];
}

finalValues = this.selectDataOld.filter(item => item[0] !== duplicateKey);
// ========== 核心修改:仅改这一行 ==========
//finalValues.push(newItem); // 旧写法:追加到末尾 → 点击后会跳回第一组
finalValues.unshift(newItem); // 新写法:插入到首位 → 组件默认展开这个项的节点

} else {
// 无重复时直接赋值
finalValues = validVals;
}

// 赋值刷新
this.$nextTick(() => {
this.selectData = […finalValues];
this.selectDataOld = […finalValues];
});
}
}
})
</script>
</body>

</html>

赞(0)
未经允许不得转载:171主机测评 » Cascader 级联选择器 一级多选 二级单选
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址