Vue电商后台管理系统-7:渲染三级权限,分配权限功能

55、角色列表:渲染一级权限

通过for循环,循环了scope.rowchildren属性,这个属性里包含了所有的一级权限,每循环一次,都往第一列里放一个tag标签,这样,经过整个for循环,所有的一级权限都会被渲染出来。

<!-- 展开列 -->
<el-table-column type="expand">
  <template slot-scope="scope">
      <el-row v-for="(item1,i1) in scope.row.children" :key="item1.id">
          <!-- 渲染一级权限 -->
          <el-col :span="5"></el-col>
          <el-tag>{{item1.authName}}</el-tag>

          <!-- 渲染二、三级权限 -->
          <el-col :span="19"></el-col>
      </el-row>
      <pre>
          {{scope.row}}
      </pre>
  </template>
</el-table-column>

在这里插入图片描述

接下来美化一级权限的UI结构:

给每个一级权限加上下横的表格线,值得注意的是,第一行需要加一条上顶线,用到了三元表达式。

<el-row :class="['bdbottom', i1 === 0 ? 'bdtop' : '']" v-for="(item1,i1) in scope.row.children" :key="item1.id">
  <!-- 渲染一级权限 -->
  <el-col :span="5"></el-col>
  <el-tag>{{item1.authName}}</el-tag>
  <i class="el-icon-caret-right"></i>
  <!-- 渲染二、三级权限 -->
  <el-col :span="19"></el-col>
</el-row>
<style lang="less" scoped>
.el-tag{
    margin: 7px ;
}
.bdtop{
    border-top: 1px solid #eee;
}
.bdbottom{
    border-bottom: 1px solid #eee;
}
</style>

在这里插入图片描述

56、角色列表:渲染二级权限

<!-- 渲染二、三级权限 -->
<el-col :span="19">
  <!-- 通过for循环,嵌套渲染二级权限 -->
  <el-row :class="[i2 === 0 ? '' : 'bdtop']" v-for="(item2, i2) in item1.children" :key="item2.id">
      <el-col>
          <el-tag type="success">{{item2.authName}}</el-tag>
          <i class="el-icon-caret-right"></i>
      </el-col>
      <el-col></el-col>
  </el-row>
</el-col>

需要注意的是,在给二级权限加边框线的时候,如果给每个都加上边框线,那么二级的第一个就会和一级的第一个重合,所以二级权限也用到了三元表达式,规则和一级不同。
在这里插入图片描述

57、角色列表:渲染三级权限

<el-col :span="6">
  <el-tag type="success">{{item2.authName}}</el-tag>
  <i class="el-icon-caret-right"></i>
</el-col>
<el-col :span="18">
  <el-tag type="warning" v-for="(item3, i3) in item2.children" :key="item3.id">
      {{item3.authName}}
  </el-tag>
</el-col>

给一级和二级列加.vcenter类,呈现垂直居中的样式。

.vcenter{
    display: flex;
    align-items: center;
}

在这里插入图片描述

58、点击删除权限按钮弹出框

先给每个tag加closable属性,可定义这个标签是否可移除。再加一个点击事件,即关闭tag时触发的事件@close="removeRightById()

在methods里定义这个触发函数:

// 根据ID删除对应的权限
async removeRightById(){
   // 弹框提示用户是否删除
   const confirmResult= await this.$confirm('此操作将永久删除该文件, 是否继续?', '提示', {
   confirmButtonText: '确定',
   cancelButtonText: '取消',
   type: 'warning'
   }).catch(err => err)
  if(confirmResult !== 'confirm') {
      return this.$message.info('取消了删除!');
  }
  console.log('确认了删除!');
}
}

在这里插入图片描述

59、完成删除权限功能

注意点:添加API接口路径时,用反引号。

// 根据ID删除对应的权限
async removeRightById(role,rightId){
    // 弹框提示用户是否删除
    const confirmResult= await this.$confirm('此操作将永久删除该文件, 是否继续?', '提示', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning'
    }).catch(err => err)
   if(confirmResult !== 'confirm') {
       return this.$message.info('取消了删除!');
   }
//    console.log('确认了删除!');
    const {data:res} = await this.$http.delete(`roles/${role.id}/rights/${rightId}`);
    if(res.meta.status !== 200) {
        return this.$message.error('删除权限失败!');
    }
        // this.getRolesList();
        role.children = res.data
}

给close事件加参数,@close="removeRightById(scope.row, item3.id)",在scope.row上包含了角色的id,item3.id是对应的权限id。

为什么一点删除按钮,tag就合上了,用户体验很不好。
因为删除完成后,会重新获取整个数据列表,页面上的table表格会被重新渲染一次,打开的状态就被立马关上了,为了防止它再次被关上,把服务器返回的data重新赋值,而不是调用getRolesList( )函数(会发生页面的完整渲染)。

<el-tag type="warning" v-for="(item3, i3) in item2.children" :key="item3.id" closable @close="removeRightById(scope.row, item3.id)">
{{item3.authName}}
</el-tag>

再将一级和二级的删除权限功能进行完整。

60、分配权限:弹出框

1、给分配权限按钮绑定click单击事件,指定一个处理函数,只要调用这个函数就会弹出框。@click=“showSetRightDialog”

2、在methods里定义这个函数:

showSetRightDialog(){ }

3、添加对应的对话框组件:

<!-- 分配权限的对话框 -->
<el-dialog title="分配权限" :visible.sync="setRightdialogVisible" width="50%">
   <span>这是一段信息</span>
   <span slot="footer" class="dialog-footer">
   <el-button @click="setRightdialogVisible = false">取 消</el-button>
   <el-button type="primary" @click="setRightdialogVisible = false">确 定</el-button>
   </span>
</el-dialog>

4、在return里定义布尔值:

// 控制分配权限对话框的显示与隐藏
setRightdialogVisible:false

5、给处理函数showSetRightDialog()重新赋值就能弹出框

showSetRightDialog(){
  this.setRightdialogVisible = true;
 }

接下来,在弹出框的同时,将分配权限的数据以一个树形图渲染出来,保存到data中,供页面实用。

上面第四步里,在布尔值变成到true之前,获取到所有权限的数据:

// 所有权限的数据
rightslist:[]


// 展示分配权限对话框
async showSetRightDialog(){
  // 获取所有权限的数据
  const {data:res} = await this.$http.get('rights/tree');
  if(res.meta.status !== 200) {
      return this.$message.error('获取权限数据失败!');
  }
  // 把获取到的权限数据保存到data中
  this.rightslist = res.data;
  console.log(this.rightslist);
  this.setRightdialogVisible = true;
}

在这里插入图片描述

61、树形控件

在分配权限的对话框里加树形控件:

 <el-tree :data="rightslist" :props="treeProps"></el-tree>

在return里:

// 树形控件的属性绑定对象
treeProps:{
    label:'authName',
    children:'children'
}

.在这里插入图片描述
再对树形控件进行优化,比如提供复选框进行勾选。并且,勾选了这个节点,就是勾选了这个节点的id值,即node-key属性。还有默认展开所有节点属性default-expand-al

<el-tree :data="rightslist" :props="treeProps" show-checkbox default-expand-all node-key="id"></el-tree>
node-key:每个树节点用来作为唯一标识的属性,整棵树应该是唯一的,字符串。
default-expand-all:是否默认展开所有节点,布尔值。

实现已有权限默认勾选:

default-checked-keys:默认勾选的节点的 key 的数组。
<el-tree :data="rightslist" :props="treeProps" show-checkbox default-expand-all node-key="id" :default-checked-keys="defKeys"></el-tree>
// 默认选中的节点id值数组
defKeys:[105, 116]

在这里插入图片描述
加载当前角色已有权限:

定义一个递归函数,将角色信息传到递归的函数中,通过递归的形式,把所有三级节点的id都保存到一个数组中,再将数组赋值给defkeys,就能实现点击分配权限按钮时,将权限默认加载出来。

如何递归,调用node里的所有数组。

// 展示分配权限对话框
async showSetRightDialog(role){
  // 获取所有权限的数据
  const {data:res} = await this.$http.get('rights/tree');
  if(res.meta.status !== 200) {
      return this.$message.error('获取权限数据失败!');
  }
  // 把获取到的权限数据保存到data中
  this.rightslist = res.data;
  console.log(this.rightslist);

 ********** // 递归获取三级节点的id   ******************************************************************************
 //这个role在当前函数中获取不到,需要在形参里定义一个
  this.getLeafKeys(role, this.defKeys);

  this.setRightdialogVisible = true;
},


// 通过递归的形式,获取角色下所有三级权限的id,并保存到 defkeys 数组中
getLeafKeys(node, arr) {
  // node 是用来判断是否是三级节点,即是否包含children属性,arr 数组用来保存
  if(!node.children) {
      // 假设是三级节点,就将 id push到数组 arr 里
      return arr.push(node.id);
  }
  //递归开始
  node.children.forEach(item =>
  this.getLeafKeys(item, arr));
}

在每次关闭分配权限对话框前,清空数组里的元素:

监听“分配权限”按钮:@close="setRightDialogClosed"

给数组defKeys重新赋值,就不会出现元素重叠的情况了:

// 监听分配权限对话框的关闭事件
setRightDialogClosed(){
  this.defKeys = [];
}

62、调用API完成分配权限功能

在这里插入图片描述
getCheckedKeys:若节点可被选择(即 show-checkbox 为 true),则返回目前被选中的节点的 key 所组成的数组。(leafOnly) 接收一个 boolean 类型的参数,若为 true 则仅返回被选中的叶子节点的 keys,默认值为 false。

getHalfCheckedKeys:若节点可被选择(即 show-checkbox 为 true),则返回目前半选中的节点的 key 所组成的数组。

先给确定按钮绑定单击事件@click="allotRights",在methods里定义这个函数:

// 当前即将分配权限的角色id
   roleId:''
  
methods:{
// 展示分配权限对话框
async showSetRightDialog(role){
  this.roleId = role.id;
     ...
}

// 点击为角色分配权限
async allotRights(){
   const keys = [
       // 复习es6语法:展开运算符,把数组转化为逗号分隔的字符串
       ...this.$refs.treeRef.getCheckedKeys(),
       ...this.$refs.treeRef.getHalfCheckedKeys()
   ]
   // console.log(keys);
   //传送到服务器里进行分配
   const idStr = keys.join(',');
   const {data:res} = await this.$http.post(`roles/${this.roleId}/rights`, {rids: idStr})
   if(res.meta.status !== 200) {
       return this.$message.error('更新权限失败!');
   }
   this.$message.success('更新权限成功!');
   this.getRolesList();
   this.setRightdialogVisible = false;
}
  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值