<template> <div class="tree-container"> <el-row :gutter="20"> <el-col :xs="24" :sm="24" :md="24" :lg="6" :xl="6"> <el-divider content-position="left">常规树</el-divider> <el-input v-model="filterText" placeholder="输入关键字过滤" /> <el-tree ref="demoTree" :data="data2" :default-checked-keys="defaultCheckedKeys" :default-expanded-keys="defaultExpendedKeys" :expand-on-click-node="false" :filter-node-method="filterNode" :highlight-current="true" :props="defaultProps" class="vab-filter-tree" node-key="id" show-checkbox @check="checkNode" @node-click="nodeClick" @node-collapse="nodeCollapse" @node-expand="nodeExpand" > <template #defalut="{ node, data }" class="vab-custom-tree-node"> <span class="vab-tree-item"> <i v-if="node.data.rank == 4" class="el-icon-s-custom"></i> {{ node.label }} </span> <span class="vab-tree-options"> <a v-if="node.data.rank !== 4" class="vab-tree-btn" title="添加" @click="() => append(node, data, 0)" > <i class="el-icon-plus"></i> </a> <a class="vab-tree-btn" title="编辑" @click="() => edit(node, data, 1)" > <i class="el-icon-edit"></i> </a> <a v-if="node.data.rank !== 1" class="vab-tree-btn" title="刪除" @click="() => remove(node, data)" > <i class="el-icon-delete"></i> </a> </span> </template> </el-tree> </el-col> <el-col :xs="24" :sm="24" :md="24" :lg="6" :xl="6"> <el-divider content-position="left">懒加载树</el-divider> <el-input v-model.lazy="keyW" :value="keyW" class="input-with-select" placeholder="请输入内容" @keyup.enter.native="showTreeList" ></el-input> <div v-show="isShow" class="blur-tree"> <el-tree ref="treeFilter" :data="filterDevLlist" :expand-on-click-node="false" :props="defaultProps" class="vab-filter-tree" default-expand-all highlight-current node-key="indexCode" @node-click="nodeClick" > <template #defalut="{ node }" class="vab-custom-tree-node"> <span class="vab-tree-item"> <i v-if="node.data.rank == 4" class="el-icon-s-custom"></i> {{ node.label }} </span> <span class="vab-tree-options"> <a v-if="node.data.rank !== 4" class="vab-tree-btn" title="添加" > <i class="el-icon-plus"></i> </a> <a class="vab-tree-btn" title="编辑"> <i class="el-icon-edit"></i> </a> <a v-if="node.data.rank !== 1" class="vab-tree-btn" title="刪除" > <i class="el-icon-delete"></i> </a> </span> </template> </el-tree> </div> <div v-show="!isShow" class="el-tree-wrap"> <el-tree ref="tree" v-loading="loading" :expand-on-click-node="false" :load="loadNode" :props="defaultProps" class="vab-filter-tree" highlight-current lazy node-key="indexCode" @node-click="nodeClick" > <template #defalut="{ node }" class="vab-custom-tree-node"> <span class="vab-tree-item"> <i v-if="node.data.rank == 4" class="el-icon-s-custom"></i> {{ node.label }} </span> <span class="vab-tree-options"> <!-- <a v-if="node.data.rank !== 4" class="vab-tree-btn" title="添加""><i class="el-icon-plus"></i></a> --> <a class="vab-tree-btn" title="编辑"> <i class="el-icon-edit"></i> </a> <a v-if="node.data.rank !== 1" class="vab-tree-btn" title="刪除" > <i class="el-icon-delete"></i> </a> </span> </template> </el-tree> </div> </el-col> <el-col :xs="24" :sm="24" :md="24" :lg="6" :xl="6"> <el-divider content-position="left">单选树</el-divider> <el-select ref="singleTree" v-model="singleSelectTreeVal" class="vab-tree-select" clearable popper-class="select-tree-popper" value-key="id" @clear="selectTreeClearHandle('single')" > <el-option :value="singleSelectTreeKey"> <el-tree id="singleSelectTree" ref="singleSelectTree" :current-node-key="singleSelectTreeKey" :data="selectTreeData" :default-expanded-keys="selectTreeDefaultSelectedKeys" :highlight-current="true" :props="selectTreeDefaultProps" node-key="id" @node-click="selectTreeNodeClick" > <template #defalut="{ node }" class="vab-custom-tree-node"> <span class="vab-tree-item">{{ node.label }}</span> </template> </el-tree> </el-option> </el-select> </el-col> <el-col :xs="24" :sm="24" :md="24" :lg="6" :xl="6"> <el-divider content-position="left">多选树</el-divider> <el-select v-model="multipleSelectTreeVal" class="vab-tree-select" clearable collapse-tags multiple popper-class="select-tree-popper" @change="changeMultipleSelectTreeHandle" @clear="selectTreeClearHandle('multiple')" @remove-tag="removeSelectTreeTag" > <el-option :value="multipleSelectTreeKey"> <el-tree id="multipleSelectTree" ref="multipleSelectTree" :current-node-key="multipleSelectTreeKey" :data="selectTreeData" :default-checked-keys="selectTreeDefaultSelectedKeys" :default-expanded-keys="selectTreeDefaultSelectedKeys" :highlight-current="true" :props="selectTreeDefaultProps" node-key="id" show-checkbox @check="multipleSelectTreeCheckNode" ></el-tree> </el-option> </el-select> </el-col> </el-row> <!--添加/编辑节点弹框-------------------start--> <el-dialog :title="dialogTitle" :visible.sync="treeDialogVisible" class="tree-operate-dialog" width="400px" @close="treeDialogVisible = false" > <el-form ref="treeForm" :model="treeForm"> <el-form-item label="节点名称" required> <el-input v-model="treeForm.name"></el-input> </el-form-item> </el-form> <div slot="footer" class="dialog-footer"> <el-button @click="treeDialogVisible = false">取 消</el-button> <el-button type="primary" @click="saveTree">确 定</el-button> </div> </el-dialog> <!--添加/编辑节点弹框-------------------end--> </div> </template> <script> import { getTreeList } from '@/api/tree' export default { name: 'Tree', data() { return { dialogTitle: '添加节点', treeFlag: 0, treeDialogVisible: false, treeForm: { id: '', name: '', }, checkNodeKeys: [], filterText: '', data2: [], defaultProps: { children: 'children', label: 'name', }, defaultExpendedKeys: [], defaultCheckedKeys: [], loading: true, keyW: '', filterDevLlist: [], isShow: false, updateTree: true, /* 单选树-多选树---------开始 */ selectLevel: 4, // 树可选叶子level等级 singleSelectTreeVal: '', //单选树默认label值 singleSelectTreeKey: '', //单选树默认key值 selectTreeData: [], //单选树的值 selectTreeDefaultSelectedKeys: [], //单选树默认展开的key值数组 selectTreeDefaultProps: { children: 'children', label: 'name', }, multipleSelectTreeVal: [], //多选树默认label值 multipleSelectTreeKey: '', //多选树默认key值 /* 单选树-多选树---------结束 */ } }, watch: { filterText(val) { this.$refs.demoTree.filter(val) }, }, mounted() { this.$nextTick(() => { this.getTreeListFuc(1) this.setCheckedKeys() // 初始化单选树 this.initSingleTree('single') // 初始化多选树 this.initSingleTree('multiple') }) }, methods: { // 树level小于n级展开方法 openTree(treeData, n) { const each = (data) => { data.forEach((e) => { if (e.rank <= n) { this.defaultExpendedKeys.push(e.id) } if (e.children.length > 0) { each(e.children) } }) } each(treeData) }, // 获取tree数据 async getTreeListFuc(flag) { const { data } = await getTreeList() this.data2 = data if (flag) { this.openTree(this.data2, 2) } }, // 节点过滤操作 filterNode(value, data) { if (!value) return true return data.name.indexOf(value) !== -1 }, // 添加节点操作 append(node, data, flag) { this.treeFlag = flag this.dialogTitle = '添加节点' this.treeForm = { id: '', name: '', } this.treeDialogVisible = true }, // 编辑节点操作 edit(node, data, flag) { this.treeFlag = flag this.dialogTitle = '编辑节点' this.treeForm = { id: data.id, name: data.name, } this.treeDialogVisible = true }, // 删除节点操作 remove(node, data) { this.$baseConfirm('你确定要删除该节点?', null, async () => { const { msg } = getTreeList() this.$baseMessage(msg, 'success') this.getTreeListFuc(0) }) }, // 保存添加和编辑 saveTree() { this.$refs.treeForm.validate(async (valid) => { if (valid) { const { msg } = await getTreeList() this.$baseMessage(msg, 'success') this.treeDialogVisible = false this.getTreeListFuc(0) } }) }, // 设置节点选中 setCheckedKeys() { this.$refs.demoTree.setCheckedKeys([1]) }, // 点击叶子节点 nodeClick(data, node, el) {}, // 节点选中操作 checkNode(data, node, el) { this.checkNodeKeys = node.checkedKeys }, // 节点展开操作 nodeExpand(data, node, el) { this.defaultExpendedKeys.push(data.id) }, // 节点关闭操作 nodeCollapse(data, node, el) { this.defaultExpendedKeys.splice( this.defaultExpendedKeys.findIndex((item) => item.id === data.id), 1 ) }, async loadNode(node, resolve) { if (node.level === 0) { const { data } = await getTreeList() this.loading = false return resolve(data) } else { const { data } = await getTreeList() return resolve(res.data) } }, //懒加载树输入框筛选方法 async showTreeList(value) { if (typeof value === 'string') { this.keyW = value.trim() } if (this.keyW.length !== 0) { // 请求后台返回查询结果 let treeOption = {} treeOption = { keyWord: this.keyW, } const { data } = await getTreeList() this.filterDevLlist = data this.isShow = true } else { this.isShow = false } }, /* 单选/多选树方法-------------------开始 */ // 初始化单选树的值 async initSingleTree(treeType) { const { data } = await getTreeList() this.selectTreeData = data this.$nextTick(() => { this.selectTreeDefaultSelectedKeys = this.singleSelectTreeKey.split(',') // 设置默认展开 if (treeType == 'single') { //单选树 this.$refs.singleSelectTree.setCurrentKey(this.singleSelectTreeKey) // 设置默认选中 } else { // 多选树 this.$refs.multipleSelectTree.setCheckedKeys( this.selectTreeDefaultSelectedKeys ) } }) }, // 清除单选树选中 selectTreeClearHandle(type) { this.selectTreeDefaultSelectedKeys = [] this.clearSelected() if (type == 'single') { this.singleSelectTreeVal = '' this.singleSelectTreeKey = '' this.$refs.singleSelectTree.setCurrentKey('') // 设置默认选中 } else { this.multipleSelectTreeVal = [] this.multipleSelectTreeKey = '' this.$refs.multipleSelectTree.setCheckedKeys([]) } }, /* 清空选中样式 */ clearSelected() { const allNode = document.querySelectorAll( '#singleSelectTree .el-tree-node' ) allNode.forEach((element) => element.classList.remove('is-current')) }, // select多选时移除某项操作 removeSelectTreeTag(val) { const stack = JSON.parse(JSON.stringify(this.selectTreeData)) while (stack.length) { const curr = stack.shift() if (curr.name == val) { return this.$refs.multipleSelectTree.setChecked(curr.id, false) } if (curr.children && curr.children.length) { stack.unshift(...curr.children) } } }, changeMultipleSelectTreeHandle(val) {}, // 点击叶子节点 selectTreeNodeClick(data, node, el) { if (data.rank >= this.selectLevel) { this.singleSelectTreeVal = data.name this.singleSelectTreeKey = data.id this.$refs.singleTree.blur() } }, // 节点选中操作 multipleSelectTreeCheckNode(data, node, el) { const checkedNodes = this.$refs.multipleSelectTree.getCheckedNodes() const keyArr = [] const valueArr = [] checkedNodes.forEach((item) => { if (item.rank >= this.selectLevel) { keyArr.push(item.id) valueArr.push(item.name) } }) this.multipleSelectTreeVal = valueArr this.multipleSelectTreeKey = keyArr.join(',') }, /* 单选/多选树方法-------------------结束 */ }, } </script>