3.1 iHRM人力资源 - 组织架构、树形结构、添加子部门

news2024/11/26 22:46:47

iHRM人力资源 - 组织架构

文章目录

  • iHRM人力资源 - 组织架构
  • 一、展示数据-树形组件
    • 1.1 组件说明
    • 1.2 树组件自定义结构获取作用域数据
      • 1.2.1 说明
      • 1.2.2 页面代码
      • 1.2.3 获取组织架构数据-api
    • 1.3 效果图
    • 1.4 修改树形结构bug
  • 二、添加子部门
    • 2.1 表单弹层
      • 2.1.1 下拉菜单点击事件
      • 2.1.2 封装弹层组件
    • 2.2 表单结构及校验
    • 2.3 部门负责人数据
    • 2.4 记录部门
    • 2.5 确认功能
    • 2.6 取消功能

一、展示数据-树形组件

树形组件:用层级结构展示信息,可展开或者折叠

image-20240312202534361

使用element-ui组件

https://element.eleme.cn/#/zh-CN/component/tree

1.1 组件说明

image-20240312205537574

<template>
  <!--为什么这里写container和app-container? 因为我们最初的时候导入过样式-->
  <div class="container">
    <!--在此容器上加了边距(上下30px,左右140px)-->
    <div class="app-container">
      组织架构
      <!--展示树形结构-->
      <!--此处正好是标签的属性名叫props,和vue框架中组件传递数据不是一个-->
      <!--default-expand-all属性表示默认将所有的树形结构打开,完整写法是 :default-expand-all=“true” (一定带冒号)-->
      <el-tree :data="depts" :props="defaultProps" default-expand-all>

      </el-tree>
    </div>
  </div>
</template>

<script>
export default {
  name: 'Department',
  data() {
    return {
      // 数组属性
      depts: [{ name: '传智教育', children: [{ name: '总裁办' }, { name: '行政部' }, { name: '人事部' }] }],
      defaultProps: {
        // 当前层级数据(在这里找此层级的显示数据)
        label: 'name',
        // 子层级(其实就是层级结构,在这里找子节点)
        children: 'children'
      }
    }
  }
}
</script>

<style scoped>
.app-container {
  padding: 30px 140px;
}
</style>

效果图

image-20240312205856054

1.2 树组件自定义结构获取作用域数据

1.2.1 说明

我们其实要实现下面的这种树形结构,在右侧还有操作地方,但是我们在1.1中只展示了名称没有显示右侧

因为element-ui中树形结构默认只显示节点的名称,如果我们想树形结构左边有内容右边也有内容的话,就需要对树形结构进行自定义

我们这个地方需要再使用一个element-ui的行和列组件

image-20240312205942385

如下图所示,我们向实现这种结构

image-20240312212147420

行 el-row

image-20240312212256238

列 el-col

其实span默认是24份,我们分配每列的空间的话,分配span值即可

image-20240312212504452

1.2.2 页面代码

我们代码要实现下面这种形式

image-20240312213737310

<template>
  <!--为什么这里写container和app-container? 因为我们最初的时候导入过样式-->
  <div class="container">
    <!--在此容器上加了边距(上下30px,左右140px)-->
    <div class="app-container">
      组织架构

      <!--展示树形结构-->
      <!--此处正好是标签的属性名叫props,和vue框架中组件传递数据不是一个-->
      <!--default-expand-all属性表示默认将所有的树形结构打开,完整写法是 :default-expand-all=“true” (一定带冒号)-->
      <el-tree :data="depts" :props="defaultProps" default-expand-all>
        <!--v-slot标签只能使用在template标签上-->
        <!--这个data数据其实是el-tree给的,下面的template模板会不断的去循环,有多少个节点就会循环多少次,把每一个数据都塞到了data里面-->
        <template v-slot="{data}">
          <!--节点结构。使用el-tree组件的插槽-->
          <!--会读取这个节点结构并循环渲染到页面上-->
          <!--我们如果把type布局模式设置为"flex",就可以用厚民安的两个属性,justify="space-between"表示两头对其,align="middle"表示垂直居中-->
          <el-row type="flex" justify="space-between" align="middle" style="width: 100%;height: 40px">
            <!--一行里面有两列,第一列是组织名称,第二列是管理员和操作(下拉菜单)-->
            <el-col>{{ data.name }}</el-col>
            <!--:span="4"一定带着冒号,因为人家想要一个数字类型-->
            <el-col :span="6">
              <span class="tree-manager">{{ data.managerName }}</span>
              <!--下拉菜单组件-->
              <el-dropdown>
                <!--显示区域内容-->
                <span class="el-dropdown-link">
                 操作<i class="el-icon-arrow-down el-icon--right"></i>
             </span>
                <!--下拉菜单的选项-->
                <el-dropdown-menu slot="dropdown">
                  <el-dropdown-item>添加子部门</el-dropdown-item>
                  <el-dropdown-item>编辑部门</el-dropdown-item>
                  <el-dropdown-item>删除</el-dropdown-item>
                </el-dropdown-menu>
              </el-dropdown>
            </el-col>
          </el-row>
        </template>
      </el-tree>
    </div>
  </div>
</template>

<script>
import { getDepartment } from '@/api/department'
import { transListToTreeData } from '@/utils'

export default {
  name: 'Department',
  data() {
    return {
      // 数组属性
      depts: [''],
      defaultProps: {
        // 当前层级数据(在这里找此层级的显示数据)
        label: 'name',
        // 子层级(其实就是层级结构,在这里找子节点)
        children: 'children'
      }
    }
  },
  // 页面初始化的时候会调用这个函数
  created() {
    // 获取部门数据,这个方法是下面methods里面的,不是api里面的
    this.getDepartment()
  },
  methods: {
    async getDepartment() {
      // 下面这个方法是import导入的api请求方法
      const result = await getDepartment()
      // 但是我们获取到的数据是列表的形式,没有层级结构,我们要使用递归的方式完成树形结构
      this.depts = transListToTreeData(result, 0)
    }
  }
}
</script>

<style scoped>
.app-container {
  padding: 30px 140px;
}

.tree-manager {
  width: 50px;
  display: inline-block;
//margin: 10px; margin-right: 50px;
}
</style>

1.2.3 获取组织架构数据-api

  1. 封装获取组织架构的API
// 引入封装的axios工具
import request from '@/utils/request'

/**
 *  获取组织架构数据
 */
export function getDepartment() {
  // request发送登录请求,会得到一个promise结果并将其返回
  return request({
    // 请求地址
    url: '/company/department',
    // 请求方式
    method: 'GET'
    // 请求参数,但是这里没有请求参数
    // data: Data
    // 在ES6中上面data: Data可以简写为 data
  })
}
  1. 初始化后调用
  // 页面初始化的时候会调用这个函数
  created() {
    // 获取部门数据,这个方法是下面methods里面的,不是api里面的
    this.getDepartment()
  },
  methods: {
    async getDepartment() {
      // 下面这个方法是import导入的api请求方法
      const result = await getDepartment()
      // 但是我们获取到的数据是列表的形式,没有层级结构,我们要使用递归的方式完成树形结构
      this.depts = transListToTreeData(result, 0)
    }
  }
  1. 赋值数据

这里我们要使用递归的方式将后端传输过来的列表数据变成树形结构

下图所示的情况

image-20240312215422002

  • 首先分析数据的关联管理

    层级结构怎么通过数据体现出来的

    如下图所示,其实就是pid与id的关系

    image-20240312220407888

{
    "success": true,
    "code": 10000,
    "data": [
        {
            "id": 1,
            "pid": 0,
            "name": "传智教育",
            "code": "CZJY",
            "managerId": 1,
            "managerName": "管理员",
            "introduce": "总部",
            "createTime": "2022-10-26 09:13:37"
        },
        {
            "id": 2,
            "pid": 1,
            "name": "总裁办",
            "code": "ZCB",
            "managerId": 1,
            "managerName": "管理员",
            "introduce": "公司战略部",
            "createTime": "2022-10-26 09:13:37"
        },
        {
            "id": 3,
            "pid": 1,
            "name": "行政部",
            "code": "XZB",
            "managerId": 4,
            "managerName": "黑马文吉星",
            "introduce": "行政部",
            "createTime": "2022-10-26 09:13:39"
        },
        ......................
    ],
    "message": "获取组织架构数据成功"
}
  • 封装递归函数根据关系转化层级结构

image-20240312220558856

/**
 * 列表数据转树形数据
 * rootValue: 其实就是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 // 将子节点赋值给当前节点
      // 我们先push再赋值childern也没关系,因为是一个对象,地址是一样的
    }
  })
  return arr
}

1.3 效果图

image-20240312222227585

1.4 修改树形结构bug

当我们点击“操作”的时候,整个树形结构会关闭或者打开,很不方便,然后我们可以将expand-on-click-nod属性设置为false,说明只有点击箭头图标的时候才会展开或者收缩节点

image-20240317231919450

<!--展示树形结构-->
<!--此处正好是标签的属性名叫props,和vue框架中组件传递数据不是一个-->
<!--default-expand-all属性表示默认将所有的树形结构打开,完整写法是 :default-expand-all=“true” (一定带冒号)-->
<el-tree :data="depts" :props="defaultProps" default-expand-all :expand-on-click-node="false">

二、添加子部门

2.1 表单弹层

我们可以将“添加”和“修改”功能公用同一个弹层,也就是“添加”和“修改”的时候公用同一个组件

大体分为两步

  1. 注册添加子部门事件
  2. 封装弹层组件
  3. 控制弹层显示隐藏

image-20240317224454360

在如下位置填写

image-20240317224945483

2.1.1 下拉菜单点击事件

 <!--下拉菜单组件-->
 <!--@command是下拉菜单的执行方法,当点击下拉菜单中的某一项的时候,就会执行operateDept方法-->
 <el-dropdown @command="operateDept">
   <!--显示区域内容-->
   <span class="el-dropdown-link">
    操作<i class="el-icon-arrow-down el-icon--right"></i>
</span>
   <!--下拉菜单的选项-->
   <el-dropdown-menu slot="dropdown">
     <el-dropdown-item command="add">添加子部门</el-dropdown-item>
     <el-dropdown-item command="edit">编辑部门</el-dropdown-item>
     <el-dropdown-item command="del">删除</el-dropdown-item>
   </el-dropdown-menu>
 </el-dropdown>

当点击某一个下拉框的时候,就会将command的值传输到type

operateDept(type) {
  alert(type)
}

效果为如下所示,这样我们就能根据不同的按钮做出不同的功能了

image-20240317225504814

2.1.2 封装弹层组件

image-20240317225913751

<template>
  <!--:visible用来控制显示和隐藏,由于我们是一个组件,所以我们需要外部传入一个参数来控制显示还是隐藏-->
  <!--@close用于监视关闭弹层(点击右上角×号的时候,就会执行此函数)-->
  <el-dialog title="新增部门" :visible="showDialog" @close="close">
    <!--放置弹层内容-->

  </el-dialog>
</template>

<script>
export default {
  // 接收外部传输过来的值
  props: {
    // 参数showDialog,类型限制为Boolean,默认值为false
    showDialog: { type: Boolean, default: false }
  },
  methods: {
    close() {
      // 修改父组件的值,子传给父亲
      // this.$emit可以触发一个自定义事件(父组件需要接收这个时间),然后把false这个值传出去
      // this.$emit('',false) 但是我们先不用这个方法
      // 这里我们使用了 sync修饰,表示会接受子组件的事件,也就是update:showDialog这个事件,然后会把值赋值给showDialog
      this.$emit('update:showDialog', false)
    }
  }
}
</script>

在index.vue组件中进行引用

<template>
  <!--为什么这里写container和app-container? 因为我们最初的时候导入过样式-->
  <div class="container">
    <!--在此容器上加了边距(上下30px,左右140px)-->
    <div class="app-container">
      组织架构

      <!--展示树形结构-->
      <!--此处正好是标签的属性名叫props,和vue框架中组件传递数据不是一个-->
      <!--default-expand-all属性表示默认将所有的树形结构打开,完整写法是 :default-expand-all=“true” (一定带冒号)-->
      <el-tree :data="depts" :props="defaultProps" default-expand-all :expand-on-click-node="false">
        <!--v-slot标签只能使用在template标签上-->
        <!--这个data数据其实是el-tree给的,下面的template模板会不断的去循环,有多少个节点就会循环多少次,把每一个数据都塞到了data里面-->
        <template v-slot="{data}">
          <!--节点结构。使用el-tree组件的插槽-->
          <!--会读取这个节点结构并循环渲染到页面上-->
          <!--我们如果把type布局模式设置为"flex",就可以用厚民安的两个属性,justify="space-between"表示两头对其,align="middle"表示垂直居中-->
          <el-row type="flex" justify="space-between" align="middle" style="width: 100%;height: 40px">
            <!--一行里面有两列,第一列是组织名称,第二列是管理员和操作(下拉菜单)-->
            <el-col>{{ data.name }}</el-col>
            <!--:span="4"一定带着冒号,因为人家想要一个数字类型-->
            <el-col :span="6">
              <span class="tree-manager">{{ data.managerName }}</span>
              <!--下拉菜单组件-->
              <!--@command是下拉菜单的执行方法,当点击下拉菜单中的某一项的时候,就会执行operateDept方法-->
              <el-dropdown @command="operateDept" >
                <!--显示区域内容-->
                <span class="el-dropdown-link">
                 操作<i class="el-icon-arrow-down el-icon--right"></i>
             </span>
                <!--下拉菜单的选项-->
                <el-dropdown-menu slot="dropdown">
                  <el-dropdown-item command="add">添加子部门</el-dropdown-item>
                  <el-dropdown-item command="edit">编辑部门</el-dropdown-item>
                  <el-dropdown-item command="del">删除</el-dropdown-item>
                </el-dropdown-menu>
              </el-dropdown>
            </el-col>
          </el-row>
        </template>
      </el-tree>
    </div>
    <!--放置弹层-->
    <!--:show-dialog 是我们在add-dept组件中定义的props-->
    <!--sync修饰,表示会接受子组件的事件,也就是update:showDialog这个事件,然后会把值赋值给下面的showDialog-->
    <add-dept :show-dialog.sync="showDialog"></add-dept>
  </div>
</template>

<script>
import { getDepartment } from '@/api/department'
import { transListToTreeData } from '@/utils'
// 引入封装的弹层组件
import AddDept from './components/add-dept.vue'

export default {
  name: 'Department',
  components: { AddDept },
  // 完成AddDept组件局部注册
  comments: { AddDept },
  data() {
    return {
      // 数组属性
      depts: [''],
      defaultProps: {
        // 当前层级数据(在这里找此层级的显示数据)
        label: 'name',
        // 子层级(其实就是层级结构,在这里找子节点)
        children: 'children'
      },
      // 控制弹层的显示和隐藏
      showDialog: false
    }
  },
  // 页面初始化的时候会调用这个函数
  created() {
    // 获取部门数据,这个方法是下面methods里面的,不是api里面的
    this.getDepartment()
  },
  methods: {
    async getDepartment() {
      // 下面这个方法是import导入的api请求方法
      const result = await getDepartment()
      // 但是我们获取到的数据是列表的形式,没有层级结构,我们要使用递归的方式完成树形结构
      this.depts = transListToTreeData(result, 0)
    },
    operateDept(type) {
      if (type === 'add') {
        // 添加子部门
        // 显示弹层组件
        this.showDialog = true
      }
    }
  }
}
</script>

<style scoped>
.app-container {
  padding: 30px 140px;
}

.tree-manager {
  width: 50px;
  display: inline-block;
//margin: 10px; margin-right: 50px;
}
</style>

2.2 表单结构及校验

image-20240317232351643

下面是基本校验

image-20240318213926528

也要完成业务校验

如:

  • 部门名称和已有部门不重复
  • 部门编码和已有编码不重复

如果不重复的话,就实行添加功能

<template>
  <!--:visible用来控制显示和隐藏,由于我们是一个组件,所以我们需要外部传入一个参数来控制显示还是隐藏-->
  <!--@close用于监视关闭弹层(点击右上角×号的时候,就会执行此函数)-->
  <el-dialog title="新增部门" :visible="showDialog" @close="close">
    <!--放置弹层内容-->
    <!--label-width设置文本的宽度,这样文本框左边的字就能对其了-->
    <el-form :model="formDara" :rules="rules" ref="addDept" label-width="120px">
      <el-form-item prop="name" label="部门名称">
        <!--place-holder是文本提示信息-->
        <el-input v-model="formDara.name" placeholder="2-10个字符" style="width: 80%" size="mini"></el-input>
      </el-form-item>
      <el-form-item prop="code" label="部门编码">
        <el-input v-model="formDara.code" placeholder="2-10个字符" style="width: 80%" size="mini"></el-input>
      </el-form-item>
      <el-form-item prop="managerId" label="部门负责人">
        <!--这个地方是一个下拉菜单-->
        <el-select v-model="formDara.managerId" placeholder="请选择负责人" style="width: 80%" size="mini">
          <!--下拉选项,循环managerList-->
          <!--label其实是下拉选项中所显示的字段名称;v-model的值为当前被选中的el-option的value属性值-->
          <el-option v-for="item in managerList" :key="item.id" :label="item.username" :value="item.id"></el-option>
        </el-select>
      </el-form-item>
      <el-form-item prop="introduce" label="部门介绍">
        <!--文本域,4行-->
        <el-input v-model="formDara.introduce" type="textarea" :rows="4" placeholder="1-100个字符" style="width: 80%"
                  size="mini"
        >
        </el-input>
      </el-form-item>
      <!--按钮部分,并且要实现居中-->
      <el-form-item>
        <!--我们可以使用行和列实现居中布局-->
        <!--justify="center" 水平方式居中-->
        <el-row type="flex" justify="center">
          <el-col :span="12">
            <el-button type="primary" size="mini">确定</el-button>
            <el-button size="mini">取消</el-button>
          </el-col>
        </el-row>
      </el-form-item>
    </el-form>
  </el-dialog>
</template>

<script>
import { getDepartment } from '@/api/department'

export default {
  // 接收外部传输过来的值
  props: {
    // 参数showDialog,类型限制为Boolean,默认值为false
    showDialog: { type: Boolean, default: false }
  },
  data() {
    return {
      formDara: {
        code: '', // 部门编码
        introduce: '', // 部门介绍
        managerId: '', // 部门负责人id
        name: '', // 部门名称,
        pid: '' // 父级部门的id
      },
      rules: {
        // 部门编码
        code: [{ required: true, message: '部门编码不能为空', trigger: 'blur' },
          { min: 2, max: 10, message: '部门编码的长度2-10个字符' },
          // 自定义业务校验,部门编码不能重复
          {
            trigger: 'blur', validator: async(rule, value, callback) => {
              // value值是输入的编码值
              const result = await getDepartment()
              // result实际是一个数组,然后查看数组中是否存在用户输入的value值
              // 我们可以使用some()方法,如果存在就返回true,不存在就返回false
              if (result.some(item => item.code === value)) {
                // 校验失败时的错误对象
                callback(new Error('部门中已经有该编码'))
              } else {
                // 校验成功时的对象
                callback()
              }
            }
          }],
        // 部门介绍
        introduce: [{ required: true, message: '部门介绍不能为空', trigger: 'blur' },
          { min: 2, max: 10, message: '部门名称的长度1-100个字符' }],
        // 部门负责人id
        managerId:
          [{ required: true, message: '部门负责人id不能为空', trigger: 'blur' }],
        // 部门名称
        name:
          [{ required: true, message: '部门名称不能为空', trigger: 'blur' },
            { min: 2, max: 10, message: '部门名称的长度2-10个字符' },
            {
              trigger: 'blur', validator: async(rule, value, callback) => {
                // value值是输入的编码值
                const result = await getDepartment()
                // result实际是一个数组,然后查看数组中是否存在用户输入的value值
                // 我们可以使用some()方法,如果存在就返回true,不存在就返回false
                if (result.some(item => item.name === value)) {
                  // 校验失败时的错误对象
                  callback(new Error('部门中已经有该名称'))
                } else {
                  // 校验成功时的对象
                  callback()
                }
              }
            }]
        // pid: '' // 父级部门的id
      }
    }
  },
  methods: {
          ......
  }
}
</script>

2.3 部门负责人数据

如下图所示

实现步骤:

  • 获取负责人的列表
  • 绑定下拉组件

image-20240318221820293

Api

/**
 * 获取部门负责人的数据
 */
export function getManagerList() {
  return request({
    url: '/sys/user/simple',
    // 请求方式
    method: 'GET'
  })
}

组件代码

data() {
  return {
    // 存储负责人的列表
    managerList: [],
  }
},
methods: {
    async getManagerList() {
      this.managerList  = await getManagerList()
    }
},
created() {
    this.getManagerList()
},    
      <el-form-item prop="managerId" label="部门负责人">
        <!--这个地方是一个下拉菜单-->
        <el-select v-model="formDara.managerId" placeholder="请选择负责人" style="width: 80%" size="mini">
          <!--下拉选项,循环managerList-->
          <!--label其实是下拉选项中所显示的字段名称;v-model的值为当前被选中的el-option的value属性值-->
          <el-option v-for="item in managerList" :key="item.id" :label="item.username" :value="item.id"></el-option>
        </el-select>
      </el-form-item>

2.4 记录部门

我们要在PHP研发部下面添加其子部门,这个时候我们要知道PHP研发部的id才可以

当我们点击PHP研发部的时候,我们需要将其id传输给AddDept组件

image-20240318225101911

我们可以先看一下父组件

image-20240318230018514

<template>
  <!--为什么这里写container和app-container? 因为我们最初的时候导入过样式-->
  <div class="container">
    <!--在此容器上加了边距(上下30px,左右140px)-->
    <div class="app-container">
      组织架构

      <!--展示树形结构-->
      <!--此处正好是标签的属性名叫props,和vue框架中组件传递数据不是一个-->
      <!--default-expand-all属性表示默认将所有的树形结构打开,完整写法是 :default-expand-all=“true” (一定带冒号)-->
      <el-tree :data="depts" :props="defaultProps" default-expand-all :expand-on-click-node="false">
        <!--v-slot标签只能使用在template标签上-->
        <!--这个data数据其实是el-tree给的,下面的template模板会不断的去循环,有多少个节点就会循环多少次,把每一个数据都塞到了data里面-->
        <template v-slot="{data}">
          <!--节点结构。使用el-tree组件的插槽-->
          <!--会读取这个节点结构并循环渲染到页面上-->
          <!--我们如果把type布局模式设置为"flex",就可以用厚民安的两个属性,justify="space-between"表示两头对其,align="middle"表示垂直居中-->
          <el-row type="flex" justify="space-between" align="middle" style="width: 100%;height: 40px">
            <!--一行里面有两列,第一列是组织名称,第二列是管理员和操作(下拉菜单)-->
            <el-col>{{ data.name }}</el-col>
            <!--:span="4"一定带着冒号,因为人家想要一个数字类型-->
            <el-col :span="6">
              <span class="tree-manager">{{ data.managerName }}</span>
              <!--下拉菜单组件-->
              <!--@command是下拉菜单的执行方法,当点击下拉菜单中的某一项的时候,就会执行operateDept方法-->
              <!--$event实参表示类型,也就是下面command中的值,表示事件所携带的默认参数,如果不传data.id的话,默认传入的就是$event实参-->
              <el-dropdown @command="operateDept($event,data.id)">
                <!--显示区域内容-->
                <span class="el-dropdown-link">
                 操作<i class="el-icon-arrow-down el-icon--right"></i>
             </span>
                <!--下拉菜单的选项-->
                <el-dropdown-menu slot="dropdown">
                  <el-dropdown-item command="add">添加子部门</el-dropdown-item>
                  <el-dropdown-item command="edit">编辑部门</el-dropdown-item>
                  <el-dropdown-item command="del">删除</el-dropdown-item>
                </el-dropdown-menu>
              </el-dropdown>
            </el-col>
          </el-row>
        </template>
      </el-tree>
    </div>
    <!--放置弹层-->
    <!--:show-dialog 是我们在add-dept组件中定义的props-->
    <!--sync修饰,表示会接受子组件的事件,也就是update:showDialog这个事件,然后会把值赋值给下面的showDialog-->
    <add-dept :current-node-id="currentNodeId" :show-dialog.sync="showDialog"></add-dept>
  </div>
</template>
methods: {
  operateDept($event, id) {
    if ($event === 'add') {
      // 添加子部门
      // 显示弹层组件
      this.showDialog = true
      // 当前点击节点的id
      this.currentNodeId = id
    }
  },
      .................
},
  data() {
    return {
      // 存储当前点击id
      currentNodeId: null,
        ............
      // 控制弹层的显示和隐藏
      showDialog: false
    }
  }

子组件进行接收

image-20240318230133070

// 接收外部传输过来的值
props: {
  // 参数showDialog,类型限制为Boolean,默认值为false
  showDialog: { type: Boolean, default: false },
  currentNodeId: {
    type: Number,
    default: null
  }
}

2.5 确认功能

点击“确认”时,首先进行表单校验,表单校验通过之后,可以将数据提交到后端也就是调用新增接口,如果调用接口成功我们就可以通知父组件更新(组织架构列表要更新),也要重置一下表单数据,再点开后是空白的情况,最后关闭弹层

image-20240318230958537

按钮

<el-button @click="btnOK" type="primary" size="mini">确定</el-button>

api请求

/**
 *  新增组织接口
 */
export function addDepartment(data) {
  return request({
    url: '/company/department',
    // 请求方式
    method: 'POST',
    data: data
  })
}

方法

 methods: {
    close() {
      // 重置表单
      this.$refs.addDept.resetFields()
      // 修改父组件的值,子传给父亲
      // this.$emit可以触发一个自定义事件(父组件需要接收这个时间),然后把false这个值传出去
      // this.$emit('',false) 但是我们先不用这个方法
      // 这里我们使用了 sync修饰,表示会接受子组件的事件,也就是update:showDialog这个事件,然后会把值赋值给showDialog
      this.$emit('update:showDialog', false)
    },
    async getManagerList() {
      this.managerList = await getManagerList()
    },
    // 点击确定时调用此方法
    btnOK() {
      this.$refs.addDept.validate(async isOK => {
        if (isOK) {
          // 校验已经通过
          // ...this.formDara 表示相当于把formDara数据进行了拷贝,考到了一个新对象里面
          // pid: this.currentNodeId表示将formDara中的pid赋值上currentNodeId
          await addDepartment({ ...this.formDara, pid: this.currentNodeId })
          // 此时可以通知父组件更新,也就是子传父,可以选择触发一个自定义事件(父组件要监听这个事件)
          this.$emit('updateDepartment')
          // 提示消息
          this.$message.success('新增部门成功')
          // 关闭
          this.close()
        }
      })
    }
  }

父组件index.vue

子组件会触发自定义事件updateDepartment

<!--放置弹层-->
<!--:show-dialog 是我们在add-dept组件中定义的props-->
<!--sync修饰,表示会接受子组件的事件,也就是update:showDialog这个事件,然后会把值赋值给下面的showDialog-->
<!--自定义事件updateDepartment,子组件触发,父组件执行getDepartment方法,刷新组织结构-->
<add-dept @updateDepartment="getDepartment" :current-node-id="currentNodeId" :show-dialog.sync="showDialog"
></add-dept>

2.6 取消功能

点击取消后,重置表单,关闭弹层即可

image-20240318231043397

<el-button @click="close" size="mini">取消</el-button>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1599887.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

中国科学院大学学位论文LaTeX模版

Word排版太麻烦了&#xff0c;公式也不好敲&#xff0c;推荐用LaTeX模版&#xff0c;全自动 官方模版下载位置&#xff1a;国科大sep系统 → \rightarrow → 培养指导 → \rightarrow → 论文 → \rightarrow → 论文格式检测 → \rightarrow → 撰写模板下载百度云&#…

Vitis HLS 学习笔记--readVec2Stream 函数-探究

目录 1. 高效内存存取的背景 2. readVec2Stream() 参数 3. 函数实现 4. 总结 1. 高效内存存取的背景 在深入研究《Vitis HLS 学习笔记--scal 函数探究》一篇文章之后&#xff0c;我们对于scal()函数如何将Y alpha * X这种简单的乘法运算复杂化有了深刻的理解。本文将转向…

前端console用法分享

console对于前端人员来讲肯定都不陌生&#xff0c;相信大部分开发者都会使用console来进行调试&#xff0c;但它能做的绝不仅限于调试。 最常见的控制台方法 作为开发者&#xff0c;最常用的 console 方法如下&#xff1a; 控制台打印结果&#xff1a; 今天我分享的是一些 co…

Vue3项目中快速引入ElementUI框架

ElementUI介绍 ElementUI是一个强大的PC端UI组件框架&#xff0c;它不依赖于vue&#xff0c;但是却是当前和vue配合做项目开发的一个比较好的ui框架&#xff0c;其包含了布局&#xff08;layout)&#xff0c;容器&#xff08;container&#xff09;等各类组件&#xff0c;基本上…

qutip,一个高级的 Python 量子力学研究库!

目录 前言 安装 特性 基本功能 量子态的创建和操作 量子态的测量 示例代码 动力学模拟 高级功能 退相干和噪声模拟 控制和优化 量子信息学工具 实际应用场景 量子态演化研究 量子计算机模拟 量子纠错协议 总结 前言 大家好&#xff0c;今天为大家分享一个高级的 Pytho…

【C++对于C语言的扩充】函数重载、引用以及内联函数

文章目录 &#x1f680;前言&#x1f680;函数重载注意&#xff1a;✈️为什么C可以实现函数重载&#xff0c;而C语言却不行呢&#xff1f; &#x1f680;引用✈️引用的特性✈️C中为什么要引入引用✈️引用与指针的区别 &#x1f680;内联函数✈️内联函数特性 &#x1f680;…

ClickHouse--17--聚合函数总结

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 环境1.创建clickhouse表2.插入数据 函数(1)count&#xff1a;计算行数(2)min&#xff1a;计算最小值(3)max&#xff1a;计算最大值(4)sum&#xff1a;计算总和&…

创新实训2024.04.11日志:self-instruct生成指令

1. 参考文献 代码&#xff1a;https://github.com/yizhongw/self-instruct论文&#xff1a;https://arxiv.org/abs/2212.10560 2. 前沿论文阅读 2.1. self-instruct技术的优势 作者在文章中提到&#xff1a; The recent NLP literature has witnessed a tremendous amount …

STM32H7的8个串口fifo收发(兼容232和485)

STM32H7的8个串口fifo收发&#xff08;兼容232和485&#xff09; 串口硬件串口时序串口高级特性同步和异步的区别单工、半双工、全双工的区别 STM32H78个串口fifo驱动定义数据结构uart_fifo.huart驱动包括中断配置等 应用示例RS485深入理解 仅供学习。 USART 的全称是 Universa…

【C++】开始使用stack 与 queue

送给大家一句话&#xff1a; 忍受现实给予我们的苦难和幸福&#xff0c;无聊和平庸。 – 余华 《活着》 开始使用queue 与 stack 1 前言2 stack与queue2.1 stack 栈2.2 queue 队列2.3 使用手册 3 开始使用Leetcode 155.最小栈牛客 JZ31 栈的弹出压入序列Leetcode 150.逆波兰表达…

Mac版2024 CleanMyMac X 4.15.2 核心功能详解 cleanmymac这个软件怎么样?cleanmymac到底好不好用?

近些年伴随着苹果生态的蓬勃发展&#xff0c;越来越多的用户开始尝试接触Mac电脑。然而很多人上手Mac后会发现&#xff0c;它的使用逻辑与Windows存在很多不同&#xff0c;而且随着使用时间的增加&#xff0c;一些奇奇怪怪的文件也会占据有限的磁盘空间&#xff0c;进而影响使用…

leetcode热题100.爬楼梯(从二进制到快速幂)

Problem: 70. 爬楼梯 文章目录 题目思路Code复杂度 题目 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢&#xff1f; 示例 1&#xff1a; 输入&#xff1a;n 2 输出&#xff1a;2 解释&#xff1a;有两种方…

Oracle+RAC静默安装系列(基于RHEL9/国产/麒麟/华为欧拉的生产案例)

由风哥发布的 OracleRAC静默安装系列&#xff08;基于RHEL9/国产/麒麟/华为欧拉的生产案例&#xff09;系列&#xff0c;适合运维人员/数据库/开发人员&#xff0c;可以用于业务生产环境。 为满足想快速安装布署Oracle数据库的学员&#xff0c;风哥特别设计的一套比较全面的全命…

DataX-Web,介绍-安装-部署-启动

使用文档&#xff1a;GitHub - WeiYe-Jing/datax-web: DataX集成可视化页面 目录 1、DataX-Web介绍 2、DataX-Web部署 3、DataX-Web启动命令 1、DataX-Web介绍 GitHub - WeiYe-Jing/datax-web&#xff1a;DataX集成可视化页面&#xff0c;选择数据源即可一键生成数据同步任务…

项目升级到jdk21后 SpringBoot相关组件的适配

了解到jdk21是一个LTS版本&#xff0c;可以稳定支持协程的功能。经过调研&#xff0c;将目前线上的jdk8升级到21&#xff0c;使用协程提升并发性能。 目前系统使用springBoot 2.0.3.RELEASE&#xff0c;并且引入了mybatis-spring-boot-starter、spring-boot-starter-data-redi…

【Entity Framework】你必须要了解EF中数据查询之数据加载

【Entity Framework】你必须要了解EF中数据查询之数据加载 文章目录 【Entity Framework】你必须要了解EF中数据查询之数据加载一、概述二、预先加载2.1 包含多个层级2.2 经过筛选的包含 三、显示加载3.1查询关联实体 四、延时加载4.1 不使用代理进行延迟加载 一、概述 Entity…

【C语言】带你完全理解指针(六)指针笔试题

目录 1. 2. 3. 4. 5. 6. 7. 8. 1. int main() {int a[5] { 1, 2, 3, 4, 5 };int* ptr (int*)(&a 1);printf("%d,%d", *(a 1), *(ptr - 1));return 0; } 【答案】 2&#xff0c;5 【解析】 定义了一个指向整数的指针ptr&#xff0c;并将其初始化为&…

设计编程网站集:动物,昆虫,蚂蚁养殖笔记

入门指南 区分白蚁与蚂蚁 日常生活中&#xff0c;人们常常会把白蚁与蚂蚁搞混淆&#xff0c;其实这两者是有很大区别的&#xff0c;养殖方式差别也很大。白蚁主要食用木质纤维&#xff0c;会给家庭房屋带来较大危害&#xff0c;而蚂蚁主要采食甜食和蛋白质类食物&#xff0c;不…

pytorch 今日小知识3——nn.MaxPool3d 、nn.AdaptiveAvgPool3d、nn.ModuleList

MaxPool3d — PyTorch 2.2 documentation 假设输入维度&#xff08;1,2,3,4,4&#xff09; maxpool torch.nn.MaxPool3d(kernel_size(2, 2, 2), stride(2, 2, 2), padding(1, 0, 0))F 维的 kernel_size 为 2&#xff0c;说明在 F 维的覆盖的 frame 数为 2&#xff0c;也就是…

Buck变换电路

Buck变换电路 Buck变换电路是最基本的DC/DC拓扑电路&#xff0c;属于非隔离型直流变换器&#xff0c;其输出电压小于输入电压。Buck变换电路具有效率高、输出稳定、控制简单和成本低的优点&#xff0c;广泛应用于稳压电源、光伏发电、LED驱动和能量回收系统。 电路原理 Buck变…