vue实现部门树
Vue 实现部门树的方法
使用递归组件实现树形结构
递归组件是 Vue 中实现树形结构的常见方式。通过组件自身调用自身,可以轻松构建多层级的部门树。
<template>
<div>
<tree-node :node="treeData"></tree-node>
</div>
</template>
<script>
import TreeNode from './TreeNode.vue'
export default {
components: { TreeNode },
data() {
return {
treeData: {
id: 1,
name: '总公司',
children: [
{
id: 2,
name: '技术部',
children: [
{ id: 3, name: '前端组' },
{ id: 4, name: '后端组' }
]
},
{
id: 5,
name: '市场部'
}
]
}
}
}
}
</script>
TreeNode.vue 组件:
<template>
<ul>
<li>
{{ node.name }}
<tree-node
v-for="child in node.children"
:key="child.id"
:node="child"
v-if="node.children"
></tree-node>
</li>
</ul>
</template>
<script>
export default {
name: 'TreeNode',
props: ['node']
}
</script>
使用第三方组件库
Element UI 和 Ant Design Vue 等流行 UI 库都提供了现成的树形组件。

使用 Element UI 的 Tree 组件:
<template>
<el-tree
:data="treeData"
:props="defaultProps"
@node-click="handleNodeClick"
></el-tree>
</template>
<script>
export default {
data() {
return {
treeData: [{
label: '总公司',
children: [{
label: '技术部',
children: [{
label: '前端组'
}, {
label: '后端组'
}]
}, {
label: '市场部'
}]
}],
defaultProps: {
children: 'children',
label: 'label'
}
}
},
methods: {
handleNodeClick(data) {
console.log(data)
}
}
}
</script>
动态加载数据
对于大型部门结构,可以采用懒加载方式,只在展开节点时加载其子节点数据。

<template>
<el-tree
:props="props"
:load="loadNode"
lazy
></el-tree>
</template>
<script>
export default {
data() {
return {
props: {
label: 'name',
children: 'children',
isLeaf: 'leaf'
}
}
},
methods: {
loadNode(node, resolve) {
if (node.level === 0) {
// 加载根节点
return resolve([{ name: '总公司' }])
}
if (node.level > 3) {
// 最多加载到第三级
return resolve([])
}
// 模拟异步加载子节点
setTimeout(() => {
const nodes = Array.from({ length: 3 }).map((_, i) => ({
name: `${node.data.name}-部门${i + 1}`,
leaf: node.level >= 2
}))
resolve(nodes)
}, 500)
}
}
}
</script>
添加交互功能
为部门树添加常见交互功能,如选择、展开/折叠、搜索等。
<template>
<div>
<el-input
placeholder="搜索部门"
v-model="filterText"
></el-input>
<el-tree
ref="tree"
:data="treeData"
:props="defaultProps"
:filter-node-method="filterNode"
show-checkbox
node-key="id"
default-expand-all
:expand-on-click-node="false"
>
<span class="custom-tree-node" slot-scope="{ node, data }">
<span>{{ node.label }}</span>
<span>
<el-button
type="text"
size="mini"
@click="() => append(data)"
>添加</el-button>
<el-button
type="text"
size="mini"
@click="() => remove(node, data)"
>删除</el-button>
</span>
</span>
</el-tree>
</div>
</template>
<script>
export default {
watch: {
filterText(val) {
this.$refs.tree.filter(val)
}
},
methods: {
filterNode(value, data) {
if (!value) return true
return data.label.indexOf(value) !== -1
},
append(data) {
// 添加子部门逻辑
},
remove(node, data) {
// 删除部门逻辑
}
}
}
</script>
与后端API集成
实际项目中,部门数据通常来自后端API,需要处理异步数据加载。
export default {
data() {
return {
treeData: []
}
},
created() {
this.fetchDepartmentTree()
},
methods: {
async fetchDepartmentTree() {
try {
const response = await axios.get('/api/departments/tree')
this.treeData = response.data
} catch (error) {
console.error('获取部门树失败:', error)
}
}
}
}






