第五天涉及到的知识点

不忘初心,虽远不怠

需求一、组织架构—添加子部门-表单结构

一、对表单结构的编写,用的是elementUI框架,效果图如下:

409f91c4d2ca794131a86281a8fbb18.png

效果图代码如下:

<el-dialog
      title="新增子部门"
      :visible="showDialog"
      @close="close"
    >
      <el-form ref="form" :model="form" :rules="rules" label-width="100px">
        <el-form-item prop="name" label="部门名称">
          <el-input v-model="form.name" placeholder="2-10个字符" />
        </el-form-item>
        <el-form-item prop="code" label="部门编码">
          <el-input v-model="form.code" placeholder="2-10个字符" />
        </el-form-item>
        <el-form-item prop="managerId" label="部门负责人">
          <el-select v-model="form.managerId" placeholder="请选择" style="width: 100%">
            <el-option
              v-for="item in managerList"
              :key="item.id"
              :label="item.username"
              :value="item.id"
            />
          </el-select>
        </el-form-item>
        <el-form-item prop="introduce" label="部门介绍">
          <el-input v-model="form.introduce" type="textarea" placeholder="1-100个字符" />
        </el-form-item>
        <div style="text-align: center">
          <el-row>
            <el-button type="primary" size="mini" @click="suerFormMsg">确定</el-button>
            <el-button type="default" size="mini" @click="close">取消</el-button>
          </el-row>
        </div>
      </el-form>
    </el-dialog>

二、对表单进行校验,在这里,我想对代码的有些注意点做个说明:

  1. ref:用来获取表单组件实例
  2. model:配合elementUI的校验方法validate对表单进行校验
  3. rules:给对应prop名称的表单元素设置校验规则
  4. 这里的部门负责人所涉及到的el-select组件里面有label和value属性,label对应的是下拉框里面的值,value与el-select组件通过v-model="form-managerID"进行双向绑定的值是一致的。
  5. 在实现添加子部门时候,需要对部门名称和部门编码进行是否与已有的数据进行判断,这里需要用到validator属性。这里用到了数组的find方法。此外,在对表单信息进行校验的时候,因为需要对输入值与接口里面的数据进行比较,所以我们这里摒弃change的实时校验。具体业务代码如下
rules: {
    name: [
      { required: true, message: '2-10个字符', trigger: ['blur'] },
      { min: 1, max: 10, message: '长度在 1 到 10 个字符', trigger: ['blur'] },
      {
        validator: async(rule, value, callback) => {
          const data = await departs()
          if (data.find(item => item.name === value)) {
            callback(new Error('部门名称已经存在了~'))
          } else {
            callback()
          }
        },
        trigger: 'blur'
      }
    ],
 code: [
      { required: true, message: '2-10个字符', trigger: ['blur'] },
      { min: 1, max: 10, message: '长度在 1 到 10 个字符', trigger: ['blur'] },
      {
        validator: async(rule, value, callback) => {
          const data = await departs()
          if (data.find(item => item.code === value)) {
            callback(new Error('部门编码已经存在了'))
          } else {
            callback()
          }
        },
        trigger: 'blur'
      }
    ]

7.在进行表单代码编写的时候,我们需要对form里面的变量名与接口文档的参数名保持一致,这样会在后面的调用接口传递数据时候带来很大的便利。

三、确认、取消功能实现

  1. 确认功能:这个需要需要处理的是当点击确认按钮后,首先需要通过this.$refs.form.validate()并配合await对表单进行校验;

  2. 封装添加子部门的接口

  3. 在校验通过后,将表单的信息发送到后端,因为这里的数据处理是在子组件AddDept里面进行的,而我们设置的表单里面的信息没有包含后端所需要的父级部门pid,所以在进行调用后端接口传递参数的时候,需要将pid,单独放到参数里面,我们可以通过配合扩展运算符进行:

      await createDepartment({ ...this.form, pid: this.departID })
    

5.通过 this.$message.success('新增部门成功')给用户做出添加成功的提示 6.重置表单并关闭弹框,因为这个在点击取消按钮也会用到同样的代码,所以我们对其做出封装

close() {
  this.$refs.form.resetFields()
  this.$emit('update:showDialog', false)
}

四、编辑部门功能的实现

  1. 这个需求的实现需要用到回显功能,回显的信息需要在子组件的弹框里面显示,在处理这个需求的时候,为了后期对代码的维护。我们将涉及到的获取数据以及显示数据的逻辑代码放入子组件里面处理。
  2. 点击添加代码的触发事件在父组件里面执行。我们先在组件上面设置ref属性addDept方便我们获取子组件实例,然后通过一下代码对子组件的事件进行触发:
// 获取当前id部门详情信息 (父组件)
    async getDepartDetailMsg() {
      this.form = await getDepartDetailMsg(this.departID)
    }

//子组件代码
    this.$nextTick(() => {
        this.$refs.addDept.getDepartDetailMsg()
    })

3、在vue中,vue更新dom的过程是异步的,这样利于提高性能,一旦数据发生变化,组件实例和dom更新渲染是异步的,所以当我们通过父组件触发子组件使其进行数据更新的时候,需要使用$nextTick()进行操作。

4、当实现编辑功能的时候,鼠标聚焦如输入框的时候,我们需要将里面的内容进行清空,即排除自身,我么你可以通过获取当前部门的id并配合filter这个方法对当前的部门信息进行过滤,完后在此基础上对部门信息进行提交

Snipaste_2023-05-28_14-52-32.png

5、当我们点击编辑部门后,鼠标聚焦在比如部门名称输入框里面,为避免鼠标聚焦后再次失焦出现错误信息提示,代码可以这样优化:

code: [
      { required: true, message: '2-10个字符', trigger: ['blur'] },
      { min: 1, max: 10, message: '长度在 1 到 10 个字符', trigger: ['blur'] },
      {
        validator: async(rule, value, callback) => {
          let data = await departs()
          if (this.form.id) {                                        // 这里是重点
            data = data.filter(item => item.id !== this.form.id)
          }
          if (data.find(item => item.code === value)) {
            callback(new Error('部门编码已经存在了'))
          } else {
            callback()
          }
        },
        trigger: 'blur'
      }
    ]

6、编辑部门的确认与取消

  1. 判断新增还是修改:通过this.form.id是否存在进行判断
  2. 技巧:传递id这个参数的时候,找小黄人里面只有数字即可,若里面的数字报红,则意味着id参数没有传递成功。
  3. 动态修改标题
  • 通过计算属性computed配合this.form.id处理,但是因为通过resetFields()重置表单只是清除表单内的数据,但是像父级部门id等表单外的数据并不会被清除,所以需要进行额外操作。
  • 我们可以在关闭弹窗的时候,将表单里面的数据进行清空。
    close() {
      this.form = {
        name: '',
        code: '',
        managerId: '',
        introduce: '',
        pid: '' // 父级部门的id
      }
      this.$refs.form.resetFields()
      this.$emit('update:showDialog', false)
    }

7、删除功能 Snipaste_2023-05-28_15-53-04.png

    //弹出确认框:
    await this.$conform('确认要删除此部门吗?', '温馨提示',{
        confirmButtonText: '确定',
        cancelButtonText: '取消'
    })
    
    调用删除的api
    await delDepartment(id)
    // 提示用户
    this.$message.success('删除部门成功')
    
    //重新获取部门列表
    this.getDepts()

问题一:编辑部门的功能如何实现

在点击下拉框编辑部门按钮的时候,出现弹窗,但是弹窗是新增子部门和编辑部门功能公用的。所以我们需要通过点击判断是否有id进行区分,有id标题为编辑功能,反之为新增子部门。然后我们通过点击获取的id,再从后端获取数据并将其渲染到表单里面。但是因为部门名称和部门编码的输入框在数据聚焦的时候会出现重复校验,这样会报错,为避免这种情况,我们需要在校验的时候需要通过在自定义校验的时候通过filter方法遍历整个数据对自身进行过滤。然后将过滤后的数据赋值给整个数据。这样就能避免当我们鼠标聚焦到输入框的时候出现错误校验。