在开发过程中遇到一个需求,需要使用到 element ui 的 el-select 嵌套 tree 树形控件
需求:点击下拉选择框,展开树形,但是只能选择到子级的,无法选择父级的
一开始的代码是这样的
<template>
<div>
<el-select v-model="searchForm.mineStatus" placeholder="请选择" clearable @clear="handleClear" ref="selectUpResId">
<el-option :value="searchForm.mineStatus" key="id" :label="label" style="height: auto">
<el-tree
:data="dataList"
:props="defaultProps"
ref="tree"
node-key="id"
:expand-on-click-node="false"
:check-on-click-node="true"
@node-click="handleNodeClick"
></el-tree>
</el-option>
</el-select>
</div>
</template>
<script>
export default {
data() {
return {
searchForm: {
mineStatus: '',
},
label: '',
dataList: [
{
id: 1,
label: '同级',
children: [
{
id: 3,
label: '海盐县公安局经侦大队',
},
{
id: 4,
label: '海盐县公安局经侦大队',
},
],
},
{
id: 2,
label: '下级部门',
children: [
{
id: 5,
label: '沈荡派出所',
},
{
id: 6,
label: '沈荡派出所',
},
],
},
],
defaultProps: {
children: 'children',
label: 'label',
},
}
},
methods: {
// 节点点击事件 三个参数:传递给 data 属性的数组中该节点所对应的对象、节点对应的 Node、节点组件本身
handleNodeClick(data, node, el) {
// 这里主要配置树形组件点击节点后,设置选择器的值;自己配置的数据
this.label = data.label
this.searchForm.mineStatus = data.id
// 选择器执行完成后,使其失去焦点隐藏下拉框的效果
this.$refs.selectUpResId.blur()
},
// 选择器配置可以清空选项,用户点击清空按钮时触发
handleClear() {
// 将选择器的值置空
this.label = ''
this.searchForm.mineStatus = ''
},
}
</script>
el-option 中 style="height: auto" 是为了让树形完全显示
一开始这样的代码会造成,点击父级会把父级的值给 el-select,不符合需求
找了很久,发现 handleNodeClick(data, node, el) 有三个参数:
- data:传递给 data 属性的数组中该节点所对应的对象
- node:节点对应的 Node
- el:节点组件本身
控制台打印的效果:
展开 node
从node 中我们可以知道 level 就是代表层级,1 即是代表父级
一开始的想法是控制 disable 来实现只能点击子级
handleNodeClick(data, node, el) {
// 这里主要配置树形组件点击节点后,设置选择器的值;自己配置的数据
if (node.level != 1) {
// 判断下拉选择的是否是1级目录
this.label = data.label
this.searchForm.mineStatus = data.id
// 选择器执行完成后,使其失去焦点隐藏下拉框的效果
this.$refs.selectUpResId.blur()
} else {
node.disabled = true
}
}
这样虽然可以实现需求,但是控制台会报错,原因是 disable 属性只能获取,无法设置,已被禁用
此时,久经思考,发现 expanded 是用来控制展开与隐藏的
那我们是不是可以判断当为父级是只控制展开
代码如下:
handleNodeClick(data, node, el) {
// 这里主要配置树形组件点击节点后,设置选择器的值;自己配置的数据
if (node.level != 1) {
// 判断下拉选择的是否是1级目录
this.label = data.label
this.searchForm.mineStatus = data.id
// 选择器执行完成后,使其失去焦点隐藏下拉框的效果
this.$refs.selectUpResId.blur()
} else {
node.expanded = !node.expanded
}
}
运行之后发现,完全可以实现
就这样,需求解决
当然,虽然使用 disable 会报错,但是也是可以实现的,但是我个人的话还是推荐 expanded 来实现,毕竟控制台一片红调试起来也不好看😁