<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>