vue实现部门管理功能
实现部门管理功能的核心模块
基础数据结构设计 部门数据通常采用树形结构存储,建议使用以下格式:
{
id: 1,
name: '技术部',
parentId: 0,
children: [
{
id: 2,
name: '前端组',
parentId: 1
}
]
}
组件结构规划
- DeptTree.vue:树形展示组件
- DeptForm.vue:表单编辑组件
- DeptTable.vue:表格列表组件
- index.vue:主入口文件整合各组件
树形组件实现方案
采用Element UI的el-tree组件构建部门树:
<template>
<el-tree
:data="deptData"
:props="treeProps"
node-key="id"
default-expand-all
@node-click="handleNodeClick">
</el-tree>
</template>
<script>
export default {
data() {
return {
treeProps: {
label: 'name',
children: 'children'
},
deptData: []
}
},
methods: {
async fetchDeptTree() {
const res = await api.getDeptTree();
this.deptData = res.data;
},
handleNodeClick(data) {
this.$emit('node-selected', data);
}
}
}
</script>
表单交互逻辑
部门表单应包含基础校验规则:
formRules: {
name: [
{ required: true, message: '请输入部门名称', trigger: 'blur' },
{ min: 2, max: 20, message: '长度在2到20个字符', trigger: 'blur' }
],
parentId: [
{ required: true, message: '请选择上级部门', trigger: 'change' }
]
}
提交逻辑需处理父子关系:
async submitForm() {
try {
const valid = await this.$refs.form.validate();
if (valid) {
const method = this.form.id ? 'updateDept' : 'addDept';
await api[method](this.form);
this.$emit('success');
}
} catch (error) {
console.error(error);
}
}
表格与树形联动
实现表格数据与树节点选择联动:
watch: {
selectedNode(val) {
if (val) {
this.queryParams.parentId = val.id;
this.loadTableData();
}
}
},
methods: {
loadTableData() {
api.getDeptList(this.queryParams).then(res => {
this.tableData = res.data;
});
}
}
完整功能整合
主入口文件示例:
<template>
<div class="dept-container">
<el-row :gutter="20">
<el-col :span="6">
<dept-tree @node-selected="handleNodeSelect"/>
</el-col>
<el-col :span="18">
<dept-table :parent-id="currentNodeId" @edit="handleEdit"/>
</el-col>
</el-row>
<dept-form
:visible="formVisible"
:data="formData"
@close="formVisible = false"
@success="handleFormSuccess"/>
</div>
</template>
关键API接口示例
后端接口建议包含:
// 获取部门树
GET /api/dept/tree
// 获取子部门列表
GET /api/dept/list?parentId=xxx
// 创建部门
POST /api/dept
// 更新部门
PUT /api/dept/:id
// 删除部门
DELETE /api/dept/:id
数据加载优化策略
采用懒加载提升大型部门树性能:
async loadNode(node, resolve) {
if (node.level === 0) {
const res = await api.getRootDepts();
resolve(res.data);
} else {
const res = await api.getChildDepts(node.data.id);
resolve(res.data || []);
}
}
移动端适配方案
针对移动设备调整布局:
@media screen and (max-width: 768px) {
.dept-container {
flex-direction: column;
}
.tree-container {
width: 100%;
margin-bottom: 20px;
}
}






