在elementPlus中el-cascader开启checkStrictly: true,会出现单选框
出现单选框之后,无法点击label来触发选中的操作了!!!
需求:需要点击label来选中对应的选项
Vue3 ElementPlus el-cascader 组
解决思路
- 获取所有的选项节点
- 监听每个节点的click事件
- 当某个节点的click事件被触发,就要找到该节点里面的redio或者checkbox,触发该表单元素的点击事件,进而实现,勾选功能。
我们需要使用 @visibleChange事件
const visibleChange = async () => {
await nextTick() //等待页面渲染完毕
setCascaderLabelEvent()
}
const setCascaderLabelEvent = () => {
//获取页面中展示的节点
let casecaderMenuList = document.querySelectorAll(
'.esg-popupConatiner .el-cascader-node',
)
let optLabels = casecaderMenuList
optLabels.forEach((item) => {
item.removeEventListener('click', (event) => {
checkOptions(event, item)
}) // 移除之前的事件监听器
//监听节点
item.addEventListener('click', (event) => {
checkOptions(event, item)
})
})
}
const checkOptions = async (event, item) => {
const input = item.querySelector(
'input[type="checkbox"], input[type="radio"]',
) // 支持复选框和单选框
if (input) {
input.click() // 模拟点击复选框
}
await nextTick() //等待渲染 完成后重新监听,当然也可以根据需求自行控制是否要关闭悬浮窗
setCascaderLabelEvent()
}
自定义label插槽时候,数据过多会出现性能问题
例如:级联选择器某个子集数据内容过多,不适用于懒加载,并且节点文字内容很长,撑满了屏幕,需要固定悬浮窗的宽度,隐藏超出内容,并且通过el-popover组件显示完整内容
通过插槽内将节点包裹一个div 监听div的鼠标移入事件 ,并将它对应的value或者唯一键赋值与响应式变量,根据变量判断是否即时单个加载部分dom
<template>
<el-cascader
style="width: 100%"
popper-class="esg-popupConatiner"
ref="cascaderRef"
@visible-change="visibleChange"
v-model="categoryName"
:options="productCategory"
:props="{
checkStrictly: true,
label: 'name',
value: 'name',
}"
>
<template #default="{ data }">
<div
class="optionNode"
@mouseenter="
() => {
hoverData = data.name
}
"
>
<el-popover
trigger="hover"
placement="left"
v-if="hoverData === data.name"
:popper-style="{
maxWidth: '400px',
width: 'auto',
}"
:content="data.name"
>
<template #reference>
{{ data.name }}
</template>
</el-popover>
<template v-else>
{{ data.name }}
</template>
</div>
</template>
</el-cascader>
</template>
<script setup>
import { ref, nextTick } from 'vue'
const hoverData = ref(null)
const visibleChange = async () => {
await nextTick()
setCascaderLabelEvent()
}
const setCascaderLabelEvent = () => {
let casecaderMenuList = document.querySelectorAll(
'.esg-popupConatiner .el-cascader-node',
)
let optLabels = casecaderMenuList
optLabels.forEach((item) => {
item.removeEventListener('click', (event) => {
checkOptions(event, item)
}) // 移除之前的事件监听器
item.addEventListener('click', (event) => {
checkOptions(event, item)
})
})
}
const checkOptions = async (event, item) => {
const input = item.querySelector(
'input[type="checkbox"], input[type="radio"]',
) // 支持复选框和单选框
if (input) {
input.click() // 模拟点击复选框
}
await nextTick()
setCascaderLabelEvent()
}
</script>
<style lang="scss">
.esg-popupConatiner {
.el-cascader-menu {
max-width: 300px;
.optionNode {
// display: block;
user-select: none;
width: 260px;
overflow: hidden;
text-overflow: ellipsis;
}
}
}
</style>