形式一:
业务需求:
1. 在树形列表中选择项目;
2. 树形列表需带有筛选过滤功能;
3. 将已选择的项目展示在输入框中;
4. 输入框中的选中项可以被单独快速删除;
5. 下拉框中可再次对之前选择过的项目进行重新选择。
实现思路:
1. 所用技术:vue + elementUI组件库;
2. 左侧:使用 el-select 下拉框多选;
右侧:使用 el-popover 弹出框 里面包含了 el-tree 树形列表进行展示。
最终效果:
1. 初始页面展示如下:
2. 点击“蓝色添加按钮”,弹出树形列表:
3. 输入关键字可直接进行筛选查询:
4. 点击右侧叶子节点进行选择,展示在左侧输入框中:
5. 输入框中的选择项可以直接点击选项后的关闭按钮取消选择,也可在下拉框列表中进行选择:
代码如下:
<!--
* @Description: select下拉多选 搭配 tree树形展示选择
-->
<template>
<div class="selectTree">
<label>发送到人:</label>
<!-- 下拉多选框 -->
<el-select class="selectStyle" v-model="selectedId" multiple placeholder="请选择">
<el-option
clearable
v-for="item in selectOptions"
:key="item.id"
:label="item.label"
:value="item.id">
</el-option>
</el-select>
<!-- 弹出框:树形选择列表 -->
<div class="treeStyle">
<el-popover
placement="right"
width="400"
trigger="click">
<!-- 树形列表的关键字过滤 -->
<el-input placeholder="输入关键字搜索" v-model="filterText">
<i slot="prefix" class="el-input__icon el-icon-search"></i>
</el-input>
<!-- 树形列表区域定高滚动 -->
<div class="popContent">
<el-tree
class="filter-tree"
:data="data"
:props="defaultProps"
default-expand-all
:filter-node-method="filterNode"
@node-click="getClickNodes"
ref="tree">
</el-tree>
</div>
<!-- 弹框外的点击按钮(即:点击此按钮后,弹框出现) -->
<div slot="reference"><img src="../../images/icon_add.png" /></div>
</el-popover>
</div>
</div>
</template>
<script>
export default {
data() {
return {
selectOptions: [], // 下拉框选择项列表
selectedId: [], // 下拉框选中值数组(多选)
filterText: '', // 输入框关键字过滤
data: [ // 树形列表展示数据
{
id: 1,
label: '张一',
children: [{
id: 2,
label: '张二',
children: [{
id: 3,
label: '张三'
}, {
id: 4,
label: '张四'
}]
}]
},
{
id: 5,
label: '王一',
children: [{
id: 6,
label: '王二'
}, {
id: 7,
label: '王三'
}]
},
{
id: 8,
label: '李一',
children: [{
id: 9,
label: '李二'
}, {
id: 10,
label: '李三'
}]
}
],
defaultProps: {
children: 'children',
label: 'label'
}
}
},
watch: {
// 输入关键字之后,过滤树形列表
filterText(val) {
this.$refs.tree.filter(val);
}
},
created() {
},
methods: {
// 过滤树形列表名称的方法
filterNode(value, data) {
if (!value) return true;
return data.label.indexOf(value) !== -1;
},
// 获取当前点击的节点信息
getClickNodes(currentData) {
// 只针对叶子节点,所以有子节点的跳过
if(currentData.children == null) {
// 第一次点击时,直接添加到下拉框的选项列表中 和 选中值中
if(this.selectOptions.length == 0) {
this.selectOptions.push(currentData)
this.selectedId.push(currentData.id)
} else {
// 第二次之后点击时,需判断是否重复(重复元素将不再添加到数组中)
// 下拉选项判重后添加
let num1 = 0;
this.selectOptions.forEach(item => {
item.id == currentData.id ? num1++ : num1;
})
if(num1 == 0) {
this.selectOptions.push(currentData)
}
// 选中值判重后添加
let num2 = 0;