depts: [
{
name: '传智教育',
children: [
{
name: '总裁办'
},
{
name: '行政部'
},
{
name: '人事部',
children: [
{
name: '财务核算部'
},
{
name: '税务管理部'
},
{
name: '薪资管理部'
}
]
}
]
}
],
defaultProps: {
label: 'name', // 要显示的字段的名字
children: 'children' // 读取子节点的字段名
}
传智教育
管理员
操作
添加子部门
编辑部门
删除
.tree-manager {
width: 50px;
display: inline-block;
margin: 10px;
}
{{ data.name }}
{{ data.managerName }}
操作
添加子部门
编辑部门
删除
depts: [
{
name: '传智教育',
managerName: '管理员',
children: [
{
name: '总裁办',
managerName: '张三'
},
{
name: '行政部',
managerName: '李四'
},
{
name: '人事部',
managerName: '王五',
children: [
{
name: '财务核算部',
managerName: '杜威'
},
{
name: '税务管理部',
managerName: '杨旭'
},
{
name: '薪资管理部',
managerName: '李生根'
}
]
}
]
}
],
defaultProps: {
label: 'name', // 要显示的字段的名字
children: 'children' // 读取子节点的字段名
}
/**
*
* 获取组织架构数据
*
*/
export function getDepartment () {
return request({
url: '/company/department',
method: 'GET'
})
}
created () {
this.getDepartment() // 调用获取数据接口
},
methods: {
async getDepartment () {
const result = await getDepartment()
this.depts = result
}
}
通过对返回数据的观察,可以发现子节点的pid是父节点的id,可以通过这个对返回数据进行处理
分析数据的关联关系
封装递归函数根据关系转化层级结构
递归特点:
①一般用来处理未知层级的数据
②递归要有跳出条件
③自身调用自身时参数不能重复
/**
* 列表型数据转化树形
*/
export function transListToTreeData (list, rootValue) {
const arr = []
list.forEach(item => {
if (item.pid === rootValue) {
// 找到了匹配的节点
arr.push(item)
// 当前节点的id和当前节点的子节点的pid是相等的
const children = transListToTreeData(list, item.id)
item.children = children // 将子节点赋值给当前节点
}
})
return arr
}
操作
添加子部门
编辑部门
删除
// 操作部门的方法
operateDept (type) {
if (type === 'add') {
// 添加子部门
this.showDialog = true
}
}
封装弹层组件
确定
取消
formData: {
code: '', // 部门编码
introduce: '', // 部门介绍
managerId: '', // 部门负责人名字
name: '', // 部门名称
pid: '' // 部门父级部门id
},
rules: {
name: [
{ required: true, message: '部门名称不能为空', trigger: 'blur' },
{
min: 2,
max: 10,
message: '部门名称的长度为2-10个字符',
trigger: 'blur'
}
], // 部门名称
code: [
{ required: true, message: '部门编码不能为空', trigger: 'blur' },
{
min: 2,
max: 10,
message: '部门编码的长度为2-10个字符',
trigger: 'blur'
}
], // 部门编码
introduce: [
{ required: true, message: '部门负责人不能为空', trigger: 'blur' },
{
min: 1,
max: 10,
message: '部门介绍的长度为1-100个字符',
trigger: 'blur'
}
], // 部门介绍
managerId: [
{ required: true, message: '部门介绍不能为空', trigger: 'blur' }
] // 部门负责人名字
}
自定义规则
{
trigger: 'blur',
// 自定义校验模式
validator: async (rule, value, callback) => {
// value就是输入的编码
const result = await getDepartment()
// result数组中是否存在value值
if (result.some(item => item.name === value)) {
callback(new Error('部门中已经有该名称了'))
} else {
callback()
}
}
}
label表示下拉菜单所显示的数据,v-model的值为当前被选中的el-option的 value 属性值
/**
*
* 获取部门负责人数据
*/
export function getManagerList () {
return request({
url: '/sys/user/simple',
method: 'GET'
})
}
managerList: [],
created () {
this.getManagerList()
},
methods: {
async getManagerList () {
this.managerList = await getManagerList()
}
}
// 操作部门的方法
operateDept (type, id) {
if (type === 'add') {
// 添加子部门
this.showDialog = true
this.currentNodeId = id
}
}
//组件接收id
currentNodeId: {
type: Number,
default: null
}
/**
*
* 新增组织
*/
export function addDepartment (data) {
return request({
url: '/company/department',
method: 'POST',
data
})
}
btnOk () {
this.$refs.addDept.validate(async isOk => {
if (isOk) {
await addDepartment({
...this.formData,
pid: this.currentNodeId
})
// 通知父组件更新
this.$emit('updateDepartment')
// 提示信息
this.$message.success('新增部门成功')
this.close()
}
})
}, close () {
// 修改父组件的值,子传父
// .sync会自动监听update:showDialog事件
this.$refs.addDept.resetFields() // 重置表单
this.$emit('update:showDialog', false)
}
/**
*
* 获取部门详情
*/
export function getDepartmentDetail (id) {
return request({
url: `/company/department/${id}`,
method: 'GET'
})
}
if (type === 'edit') {
// 编辑部门
this.showDialog = true
this.currentNodeId = id // 记录id 要用它获取数据
// 更新props是异步动作,直接调用子组件的方法是同步方法
// 所以这里要使用$this.$nextTick方法等数据都处理完,在执行方法
// 要在子组件获取数据
// 父组件调用子组件的方法来获取数据
this.$nextTick(() => {
this.$refs.addDept.getDepartmentDetail() // this.$refs.addDept
})
}
// 获取组织的详情
async getDepartmentDetail () {
this.formData = await getDepartmentDetail(this.currentNodeId)
}
let result = await getDepartment()
// 判断是否是编辑模式
if (this.formData.id) {
// 编辑场景
result = result.filter(item => item.id !== this.formData.id)
}
标题不是表单所以不能绑定v-model事件,使用计算属性进行更新
/**
*
* 更新部门
*/
export function updateDepartment (data) {
return request({
url: `/company/department/${data.id}`,
method: 'PUT',
data
})
}
// 标题不是表单所以不能绑定v-model事件,使用计算属性进行更新
computed: {
showTitle () {
return this.formData.id ? '编辑部门' : '新增部门'
}
}
close () {
// 修改父组件的值,子传父
// .sync会自动监听update:showDialog事件
// resetFields只能重置在模板中绑定的数据
this.formData = {
code: '', // 部门编managerList
introduce: '', // 部门介绍
managerId: '', // 部门负责人名字
name: '', // 部门名称
pid: '' // 部门父级部门id
}
this.$refs.addDept.resetFields() // 重置表单
this.$emit('update:showDialog', false)
}
btnOk () {
this.$refs.addDept.validate(async isOk => {
if (isOk) {
let msg = '新增'
// 通过formData中id判断属于什么场景
if (this.formData.id) {
// 编辑场景
await updateDepartment(this.formData)
msg = '更新'
} else {
// 新增场景
await addDepartment({
...this.formData,
pid: this.currentNodeId
})
}
// 通知父组件更新
this.$emit('updateDepartment')
// 提示信息
this.$message.success(`${msg}新增部门成功`)
this.close()
}
})
},
/**
*
* 删除部门
*/
export function delDepartment (id) {
return request({
url: `/company/department/${id}`,
method: 'DELETE'
})
}
// 删除部门
this.$confirm('您确定要删除该部门吗').then(async () => {
await delDepartment(id)
// 提示消息
this.$message.success('删除部门成功')
this.getDepartment()
})