第六天技术总结——角色管理(核心—编辑功能)

一、布局

<div class="roleCont">
    <el-button type="primary" size="small">添加角色</el-button>
    <el-table>
      <el-table-column align="center" width="200" label="角色" />
      <el-table-column align="center" width="200" label="启用" />
      <el-table-column align="center" label="描述" />
      <el-table-column align="center" label="操作" />
    </el-table>
    <el-row type="flex" justify="end" align="center" style="height: 60px">
      <el-pagination
        :current-page="currentPage"
        :page-size="100"
        layout="total, prev, pager, next"
        @current-change="handleCurrentChange"
      />
    </el-row>
</div>

注意点:flex布局的使用需要熟悉。

二、新建接口文件

Snipaste_2023-05-28_16-51-13.png
  1. 这里的传参需要加大括号,注意下
  2. 报错:意思是:在当前表达式前面添加await没意义;下面这个报错是因为在封装接口的时候没有return

Snipaste_2023-05-28_17-38-11.png Snipaste_2023-05-28_17-11-37.png

3、插槽的使用。当从后端获取到的数据与渲染的数据不一样时,需要用到插槽对数据进行转换

<template #default="{row}">
  {{ row.state === 1 ? '已启用' : row.state === 0 ? '未启用' : '无' }}
</template>

4、文本按钮

    <el-button type="text">我是文本按钮</button>

5、分页功能

Snipaste_2023-05-28_17-42-33.png
注意点:点击切换的时候,先去修改页码,再去调用更新数据的方法

6、添加角色

Snipaste_2023-05-28_18-11-49.png

三、角色管理—编辑角色—行内编辑

Snipaste_2023-05-29_09-30-20.png

1、给每一项添加变量isEdit(是否进入编辑状态,默认不编辑)

2、为了让点击编辑的时候能获取当前行的数据,需要加上插槽

3、点击编辑将isEdit变为true,进入编辑状态

 <template>
    <el-input v-if="row.isEdit" >
    <span>{{row.name}}</span>
</template>

4、修改角色:此处为了对角色做出操作,也需要template插槽配合进行,但是当我们点击编辑按钮的时候,并没有出现想要的切换。原因在于在vue中动态添加的属性,不具备响应式的能力。(vue底层使用了Object.defineProperty属性)

5、如何动态的往对象中添加属性,且还具备响应式能力? this.$set(目标对象,属性,属性值),这样就使得vue具备动态添加属性值的能力。所以我们在初始化数据的时候,通过对获取到的数据每一项进行遍历添加isEdit属性。

   // 给每个数据添加isEdit属性
  this.tableList.forEach(item => {
    this.$set(item, 'isEdit', false)
  })

6、template也可作为空标签,被解析之后,不会解析任何的节点能提升性能。从下面的对比中可以看出使用template的节点要少于使用el-row的节点情况

Snipaste_2023-05-29_10-10-59.png

Snipaste_2023-05-29_10-22-57.png

Snipaste_2023-05-29_10-12-04.png

Snipaste_2023-05-29_10-23-17.png

三、角色管理—编辑角色—行内数据缓存

  1. 初始化定义缓存数据,因为是动态添加,需要使用this.$set方法
Snipaste_2023-05-29_10-37-17.png
this.$edit(item, 'rowEdit', {
    
})

2、点击编辑对数据进行编辑的时候,但是经过取消操作后,再进行编辑的话,此时的数据应该与界面初始化的数据保持一致。然而,出现的还是编辑后的值,这个逻辑是不对的。所以我们需要在点击编辑的时候,将row里面的name、state和description赋值给rowEdit里面相对应的值。

// 给每行数据添加rowEdit缓存数据
this.$set(item, 'rowEdit', {
  name: item.name,
  description: item.description,
  state: item.state
})

再给对应的表单元素进行值的双向绑定 v-model="row.rowEdit.name/description/state"

每次点击编辑的时候对rowEdit进行再赋值

row.rowEdit = {
    name: row.name,
    state: row.state,
    description: row.description
 }
 

四、角色管理—确定编辑的角色 点击确定按钮的时候,判断row.rowEdit.name && row.rowEdit.description是否为空

点击事件() {
    if(row.rowEdit.name && row.rowEdit.description) {
        await updateRole({...row.rowEdit, id: row.id})
        
        row.name = row.rowEdit.name  //但是这样eslint工具会报错(误报)
        
        所以这样写:相同的,后者覆盖前者,不相同的话后者与前者合并
        
        Object.assign(row, {
            ...row.rowEdit,
            isEdit: false
        })
    }else{
        this.$message.warning('角色或描述不能为空')
    }
}

五、实现删除功能 使用elementui的Popconfirm气泡确认框组件,这个组件的使用方法上有个bug,就是点击它弹窗里面的确认按钮所触发的时间不是confirm而是onConfirm,包括取消的cancel也是onCancel才会生效。