主要功能: 多选,移除标签,清空标签,模糊搜索,禁用,全选,清空
<template>
<el-select
v-model="selectValue"
multiple
placeholder="请选择"
:popper-append-to-body="true"
@remove-tag="removeTag"
collapse-tags
collapse-tags-tooltip
@clear="clearAll"
clearable
filterable
:filter-method="filterMethod"
>
<el-option
v-loading="treeLoading"
:value="selectTree"
element-loading-background="rgba(255, 255, 255, 0.5)"
element-loading-text="loading"
class="option-style"
disabled
>
<div class="check-box">
<el-button type="primary" text @click="handleCheckAll">全选</el-button>
<el-button type="primary" text @click="clearAll">清空</el-button>
</div>
<el-tree
:data="fileTypeTree"
:props="treeProps"
ref="tree"
show-checkbox
:expand-on-click-node="false"
node-key="id"
check-on-click-node
highlight-current
@check="handleCheckClick"
:filter-node-method="filterNode"
class="tree-style"
></el-tree>
</el-option>
</el-select>
</template>
<script>
import 'element-plus/dist/index.css'
import { getFileTypeTree } from '@/api/Customer/index'
export default {
name: 'App',
data() {
return {
noticeTypeId: [], // 最后获取的选择id
treeProps: {
value: 'id',
label: 'name',
children: 'children',
isLeaf: 'isLeaf',
},
fileTypeTree: [],
selectValue: [], // 文本框中的标签
selectTree: [], // 绑定el-option的值
treeLoading: false,
}
},
async created() {
// 树结构数据
const resFile = await getFileTypeTree()
if (resFile.data.code === 20000) {
this.fileTypeTree = resFile.data.data
}
// 如果noticeTypeId有初始值,需要加入以下代码回显值
this.$nextTick(() => {
this.noticeTypeId.forEach((v) => {
this.$refs.tree.setChecked(v, true, true)
})
})
this.selectTree = this.flattenTree(this.fileTypeTree)
// 筛选出匹配的对象并返回其 name 属性
this.selectValue = this.selectTree
.filter((item) => this.noticeTypeId.includes(item.id)) // 过滤出id匹配的数据
.map((v) => ({
label: v.name,
value: v.id,
}))
},
methods: {
// 平铺树状结构
flattenTree(tree) {
const result = []
function traverse(node) {
result.push({
id: node.id,
name: node.name,
})
if (node.children && node.children.length > 0) {
node.children.forEach((child) => traverse(child))
}
}
tree.forEach((rootNode) => traverse(rootNode))
return result
},
// 全选
handleCheckAll() {
this.treeLoading = true
setTimeout(() => {
this.$refs.tree.setCheckedNodes(this.fileTypeTree)
this.treeLoading = false
}, 200)
this.selectTree = this.flattenTree(this.fileTypeTree)
this.selectValue = this.selectTree.map((v) => ({
label: v.name,
value: v.id,
}))
this.noticeTypeId = this.selectTree.map((v) => v.id)
},
/**
* @description: 勾选树形选项
* @param {*} data 传递给 data 属性的数组中该节点所对应的对象
* @param {*} node 树目前的选中状态对象,包含 checkedNodes、checkedKeys、halfCheckedNodes、halfCheckedKeys 四个属性
* @return {*}
*/
handleCheckClick(data, node) {
console.log('handleCheckClick----', data, node)
this.selectTree = node.checkedNodes
this.selectValue = this.selectTree.map((v) => ({
label: v.name,
value: v.id,
}))
this.noticeTypeId = node.checkedKeys
},
removeTag(tag) {
this.selectValue = this.selectValue.filter((v) => v.id !== tag.value)
this.selectTree = this.selectTree.filter((v) => v.id !== tag.value)
this.noticeTypeId = this.selectTree.map((v) => v.id)
this.$nextTick(() => {
this.$refs.tree.setCheckedNodes(this.selectTree)
})
},
clearAll() {
this.treeLoading = true
this.selectTree = []
this.selectValue = []
this.noticeTypeId = []
setTimeout(() => {
this.fileTypeTree.forEach((v) => {
this.$refs.tree.setChecked(v.id, false, true) // 在树状结构没有展开时,使用setChecked才能改变节点状态
})
this.treeLoading = false
}, 200)
},
// 输入框关键字
filterMethod(val) {
this.$refs.tree.filter(val)
},
/**
* @description: tree搜索过滤
* @param {*} value 搜索的关键字
* @param {*} data 筛选到的节点
* @return {*}
*/
filterNode(value, data) {
if (!value) return true
return data.name.toLowerCase().indexOf(value.toLowerCase()) !== -1
},
},
}
</script>