在 `iview v4.3.1` 中是不提供 `select-tree` 组件的,但实际业务场景中却会有需求。
下面是自己封装的基于 `iview` 的结合 `select` 与 `tree` 的组件。
- 目前基本满足了当前业务场景的功能使用
- 但还缺少一些高阶的功能使用(比如说 `iview` 中 `select` 的输入筛选 `filterable` ),因为需要实现的功能没有那么多,就没有再拓展,感兴趣者可自行尝试。
~~~
<!--
* @Author: pimzh
* @Date: 2020-10-14 10:37:21
* @LastEditTime: 2020-10-15 14:27:42
* @LastEditors: pimzh
* @Description: select tree 组件
-->
<template>
<div :class="prefixCls">
<i-select
v-bind="$attrs"
:value="selectVal"
>
<Option :value="selectVal">{{ selectLabel }}</Option>
<Tree v-bind="$attrs" :data="treeData" @on-select-change="handleSelectChange" />
</i-select>
</div>
</template>
<script>
const prefixCls = "select-tree";
export default {
name: "select-tree",
data() {
return {
prefixCls: prefixCls,
selectVal: "",
selectLabel: "",
treeData: []
};
},
props: {
data: {
type: Array,
default: () => []
},
value: [String, Number, Array]
},
watch: {
value: {
handler(val) {
if (val) {
this.selectVal = val;
}
},
immediate: true
},
data: {
handler(val) {
if (this.value) {
// 初始化若有value展开到value所在的节点
this.treeData = this.loopArr(JSON.parse(JSON.stringify(val)));
} else {
this.treeData = JSON.parse(JSON.stringify(val));
}
},
deep: true,
immediate: true
}
},
methods: {
// 遍历数据展开节点
loopArr(treeArr) {
const { value } = this;
let isFind = false;
const loop = arr => {
const newArr = [];
arr.forEach(item => {
if (!isFind) {
item.expand = true;
// 在当前节点已找到
if (item.value === value) {
isFind = true;
item.expand = false;
item.selected = true;
this.selectLabel = item.title;
} else if (item.children && item.children.length > 0) {
loop(item.children);
// 在子节点还未找到
if (!isFind) {
item.expand = false;
}
}
}
newArr.push(item);
});
return newArr;
};
return loop(treeArr);
},
// 点击树节点时触发
handleSelectChange(data, item) {
if (this.selectVal === item.value) {
// 重复点击同一个节点时依然保持选中状态
item.selected = true;
} else {
// 不需要重复点击同一个节点时重新赋值
this.selectLabel = item.title;
this.selectVal = item.value;
this.$emit("on-select-change", item);
}
}
}
};
</script>
<style lang="scss" scoped>
.select-tree {
/deep/ .ivu-select {
&-item {
display: none;
}
&-dropdown {
height: 8.5rem;
padding-left: 0.2rem;
.ivu-tree ul li {
margin: 0;
}
}
}
}
</style>
~~~