后台管理系统之权限管理页面

首先创建权限管理页面,然后在router中注册好路由,实现了跳转之后,就在权限管理页面实现获取数据,然后把数据存起来,然后把数据展示出来

<template>
  <div>
    <!-- 面包屑区域 -->
    <el-breadcrumb separator-class="el-icon-arrow-right">
      <el-breadcrumb-item :to="{ path: '/home' }">首页</el-breadcrumb-item>
      <el-breadcrumb-item>权限管理</el-breadcrumb-item>
      <el-breadcrumb-item>权限列表</el-breadcrumb-item>
    </el-breadcrumb>
    <el-card>
      <el-table :data="rights" border script>
        <el-table-column label="id" type="index" width="120px"></el-table-column>
        <el-table-column label="权限说明" prop="authName"></el-table-column>
        <el-table-column label="权限层次" prop="level">
          <template slot-scope="scope">
            <el-tag type="info" v-if="scope.row.level === '0'">等级一</el-tag>
            <el-tag type="warning" v-else-if="scope.row.level === '1'">等级二</el-tag>
            <el-tag type="danger" v-else>等级三</el-tag>
          </template>
        </el-table-column>
        <el-table-column label="路径" prop="path"></el-table-column>
      </el-table>
    </el-card>
  </div>
</template>
<script>
export default {
  data() {
    return {
      rights: []
    }
  },
  created () {
    this.getRights()
  },
  methods: {
    async getRights() {
      const { data: res } = await this.$http.get('rights/list')
      if (res.meta.status !== 200) return this.$message.error('获权限列表失败')
      this.rights = res.data
    }
  }

}
</script>

<style>

</style>

现在设计权限分层的特效
第一步,使用作用域插槽,因为压要数据,把权限进行好布局,使用layout布局,前面使用row占5个部分,然后循环把一级权限取出来

<!-- 展开列 -->
<el-table-column type="expand">  //使用这个type可以实现点击那个箭头会在行下面展开一个空白页面
  <template slot-scope="scope">
    <el-row v-for="item in  scope.row.children" :key="item.id">
      <el-col :span="5">
        <el-tag>{{item.authName}}</el-tag>
      </el-col>
      <el-col :span="19"></el-col>
    </el-row>
  </template>
</el-table-column>

在这里插入图片描述
然后二三级权限的布局

<el-table-column type="expand">
  <!-- 通过作用域获取数据 -->
  <template slot-scope="scope">
    <!-- 通过分行布局 class是为了使每一个权限上面有边框线 -->
    <el-row v-for="(item, index) in  scope.row.children" :key="item.id" :class="['dbbottom',index === 0 ? 'bdtop' : '']">
      <!-- 一级权限使用5个部分 -->
      <el-col :span="5">
        <el-tag >{{item.authName}}</el-tag>
        <i class="el-icon-caret-right"></i>
      </el-col>
      <!-- 二级权限 -->
      <el-col :span="19">
        <!-- 再创建一个row来分二级和三级权限 -->
        <el-row v-for="(item2, index2) in item.children" :key="item2.id" :class="[index2 === 0 ? '' : 'bdtop']">
          <!-- 二级权限 -->
          <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 in item2.children" :key="item3.id">{{item3.authName}}</el-tag>
          </el-col>
        </el-row>
      </el-col>
    </el-row>
  </template>
</el-table-column>

然后进行优化,如果缩小敞口大小,权限布局会乱掉,所以需要加一个最小的宽度
下面代码的效果就是如果宽度不够的话,会强制把把宽度变成设置的大小
后台管理系统之权限管理页面_第1张图片
然后想要居中

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

然后想要给tag设置一个可以删除的样子
后台管理系统之权限管理页面_第2张图片
加了closable 还有在关闭的时候产生的close事件,然后这个close事件就对应删除权限的方法,然后传删除角色的信息和删除权限的id

  <!-- 三级权限 -->
  <el-col :span="18">
    <el-tag closable  type="warning" v-for="item3 in item2.children" :key="item3.id" @close="removeTag(scope.row, item3.id)">{{item3.authName}}</el-tag>
  </el-col>

然后

/* 删除权限 */
async removeTag(role, rightId) {
  /* 是否选择删除 */
  const confirmresult = await this.$confirm('此操作将永久删除该文件, 是否继续?', '提示', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning'
  }).catch(err => err)
  if (confirmresult !== 'confirm') return this.$message.info('取消了删除')
  /* 确认删除  */
  const { data: res } = await this.$http.delete(`roles/${role.id}/rights/${rightId}`)
  if (res.meta.status !== 200) return this.$message.error('删除失败')
  // this.getuserRoles() 直接使用请求来获取最新的数据会产生刷新一样的bug,就是把expand关上
  // 由于文档里说会响应返回最新的data,只需要把datad的数据放到role的孩子权限那里就可以了就可以了
  role.children = res.data
}

现在来实现权限的树形结构
首先把一个对话框放在card外面,然后在点击分配权限的时候拿出来,并且获取到所有权限的数据

/* 分配权限 */
async showsetRight() {
  /* 获取权限数据 */
  const { data: res } = await this.$http.get('rights/tree')
  if (res.meta.status !== 200) return this.$message.error('获取失败')
  //把数据存储起来
  this.rightsTree = res.data
  /* 展示框 */
  this.setRightdialogVisible = true
}

然后把树形控件复制进来,并且去elementui插件哪里声明和使用一下
树形控件中,data绑定的是所有权限数据,比如上面获取到的数据,然后prop绑定的是如何分配权限

<!-- 分配权限对话框 -->
    <el-dialog
      title="分配权限"
      :visible.sync="setRightdialogVisible"
      width="50%">
      <!-- 树形控件 -->
     <el-tree :data="rightsTree" :props="treeProps" ></el-tree>
     <!-- 脚部的确定与取消 -->
      <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>

prop绑定的数据要在data生声明一下

  data () {
    return {
      userRoles: [],
      setRightdialogVisible: false,
      rightsTree: [],
      treeProps: {   //绑定这里
        label: 'authName',  //这里的是展示权限的名字
        children: 'children'   //这里是展示权限的地方
      }
    }
  },

后台管理系统之权限管理页面_第3张图片
现在来优化
要实现下面这个样子

 <!-- 树形控件  show-checkbox表示可以选择 node-key表示绑定id这个值 default-expand-all表示默认展开  -->
 <el-tree :data="rightsTree" :props="treeProps"  show-checkbox node-key="id" default-expand-all></el-tree>

后台管理系统之权限管理页面_第4张图片
下面来实现点开上面的树状图时,默认选手角色拥有的权限
这里使用到的就是tree控件的, :default-checked-keys = defKey ,通过绑定defkey数组里面的权限的id来实现哪一个权限被选中
首先使用

  <!-- 树形控件  show-checkbox表示可以选择 node-key表示绑定id这个值 default-expand-all表示默认展开  -->
 <el-tree :data="rightsTree"
  :props="treeProps"
  show-checkbox
  node-key="id"
  default-expand-all
  :default-checked-keys = defKey //这里这个属性
  ></el-tree>

然后定义完那个数组之后,写一个递归方法,通过递归把三级权限拿出来,然后存到数组里面就可以实现了

/* 递归方法来把角色拥有的权限通过递归把第三级权拿出来 */
getLearfKeys(node, arr) {
  if (!node.children) return arr.push(node.id)
  node.children.forEach(item => {
    this.getLearfKeys(item, arr)
  })
}

然后在点击的时候

/* 分配权限 */
async showsetRight(role) {
  /* 获取权限数据 */
  const { data: res } = await this.$http.get('rights/tree')
  if (res.meta.status !== 200) return this.$message.error('获取失败')
  this.rightsTree = res.data
  /* 展示框 */
  this.setRightdialogVisible = true
  /* 调用递归方法,把角色拥有的权限存到defkey数组里面 */
  this.getLearfKeys(role, this.defKey)  //把值传进去用就可以了
},

但是这个时候会产生一个bug,每一个点击这个按钮都会填充defkey数组,所以点其他角色的时候会把没有他权限也展示出来,所以在关闭对话框的时候,就清空一下数组就可以了

然后下面真的来是实现分配权限在选中的权限都从新分配给角色
首先就是拿到选中和半选中的权限,然后把他们的id放到一个数组里面,然后拿到当前点击的是哪一个角色的id,然后通过当前角色的id和权限的id发送请求就可以实现更改用户权限了
首先在对话框绑定一个点击事件,然后创一个数组,数组里面使用tree控件的两个方法把全选中和半选中的权限id放到数组里

/* 点击确定的时候分配权限 */
async setRight() {
  /* getCheckedKeys拿到全选中的权限的id,getHalfCheckedKeys半选中的id */
  /* 通过ref拿到树控件放到数组里 */
  const treeId = [
    ...this.$refs.trees.getCheckedKeys(),
    ...this.$refs.trees.getHalfCheckedKeys()
  ]
  /* 因为对应的是字符串所以要改成字符串 */
  const tId = treeId.join(',')
  const { data: res } = await this.$http.post(`roles/${this.roleId}/rights`, { rids: tId })
  if (res.meta.status !== 200) return this.$message.error('分配错误')
  this.$message.success('分配成功')
  this.getuserRoles()
  this.setRightdialogVisible = false
}

你可能感兴趣的:(vue)