IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> 笔记7:权限管理功能【Vue实战项目:电商管理系统(Element-UI)】 -> 正文阅读

[JavaScript知识库]笔记7:权限管理功能【Vue实战项目:电商管理系统(Element-UI)】

1 权限列表

在这里插入图片描述

1.1 通过路由展示权限列表组件

  • 创建页面:../components/power/Rights.vue
<template>
  <div>
    <!-- 面包屑导航 -->
    <el-breadcrumb separator-class="el-icon-arrow-right">
      <el-breadcrumb-item :to="{ path: '/welcome' }">首页</el-breadcrumb-item>
      <el-breadcrumb-item>权限管理</el-breadcrumb-item>
      <el-breadcrumb-item>权限列表</el-breadcrumb-item>
    </el-breadcrumb>
    
    <!-- 卡片区域 -->
    <el-card> 权限列表表单</el-card>
  </div>
</template>

<script>
export default {};
</script>

<style lang="less" scoped>
</style>
  • 添加路由
import Rights from '../components/power/Rights.vue'

Vue.use(Router)

const router = new Router({
  routes: [
    ...
    {
      path: '/home', component: Home, redirect: '/welcome', children: [
        ...,
        { path: '/rights', component: Rights }
      ]
    }
  ]
})

在这里插入图片描述

1.2 调用API获取权限列表的数据

<script>
export default {
  data() {
    return {
      rightsList: [],
    };
  },
  created() {
    this.getRightsList();
  },
  methods: {
    async getRightsList() {
      const { data: res } = await this.$http.get("rights/list");
      if (res.meta.status !== 200) {
        return this.$message.error("获取权限列表失败!");
      }

      this.rightsList = res.data;
      console.log(this.rightsList);
    },
  },
};
</script>

1.3 渲染权限列表UI结构

<el-table :data="rightsList" stripe border>
    <el-table-column type="index" label="序号"> </el-table-column>
    <el-table-column prop="authName" label="权限名称">
    </el-table-column>
    <el-table-column prop="path" label="路径">
    </el-table-column>
    <el-table-column prop="level" label="权限等级">
      <!-- 作用域插槽 -->
      <template slot-scope="scope">
        <el-tag v-if="scope.row.level === '0'">一级</el-tag>
        <el-tag type="success" v-else-if="scope.row.level === '1'">二级</el-tag>
        <el-tag type="warning" v-else>三级</el-tag>
      </template>
    </el-table-column>
</el-table>

2 权限管理

在这里插入图片描述

2.1 绘制基本布局结构并获取列表数据

  • 创建页面:../components/power/Roles.vue
<template>
  <div>
    <!-- 面包屑导航 -->
    <el-breadcrumb separator-class="el-icon-arrow-right">
      <el-breadcrumb-item :to="{ path: '/welcome' }">首页</el-breadcrumb-item>
      <el-breadcrumb-item>权限管理</el-breadcrumb-item>
      <el-breadcrumb-item>角色列表</el-breadcrumb-item>
    </el-breadcrumb>

    <!-- 卡片视图 -->
    <el-card>
      <!-- 添加角色按钮 -->
      <el-row>
        <el-col>
          <el-button type="primary">添加角色</el-button>
        </el-col>
      </el-row>
      <!-- 角色列表区域 -->
    </el-card>
  </div>
</template>

<script>
export default {};
</script>

<style lang="less" scoped>
</style>
  • 设置路由
import Roles from '../components/power/Roles.vue'

Vue.use(Router)

const router = new Router({
  routes: [
    ...
    {
      path: '/home', component: Home, redirect: '/welcome', children: [
        ...
        { path: '/roles', component: Roles },
      ]
    }
  ]
})
  • 获取接口数据

1.5.1. 角色列表接口

<script>
export default {
  data() {
    return {
      rolesList: [],
    };
  },
  created() {
    this.getRolesList();
  },
  methods: {
    async getRolesList() {
      const { data: res } = await this.$http.get("roles");
      if (res.meta.status !== 200) {
        return this.$message.error("获取角色列表失败!");
      }

      this.rolesList = res.data;
      console.log(this.rolesList);
    },
  },
};
</script>

2.2 渲染角色列表数据

  <!-- 角色列表区域 -->
  <el-table :data="rolesList" stripe border>
    <!-- 展开列 -->
    <el-table-column type="expand"> </el-table-column>
    <!-- 索引列 -->
    <el-table-column type="index" label="#"> </el-table-column>
    <el-table-column prop="roleName" label="角色名称"> </el-table-column>
    <el-table-column prop="roleDesc" label="角色描述"> </el-table-column>
    <el-table-column label="操作">
      <!-- 作用域插槽 -->
      <template slot-scope="scope">
        <el-button size="mini" type="primary" icon="el-icon-edit"
          >编辑</el-button
        >
        <el-button size="mini" type="danger" icon="el-icon-delete"
          >删除</el-button
        >
        <el-button size="mini" type="warning" icon="el-icon-setting"
          >分配权限</el-button
        >
      </template>
    </el-table-column>
  </el-table>

在这里插入图片描述

2.3 通过第一层for循环渲染一级权限

  • 在展开列添加作用域插槽,来展示数据
<!-- 展开列 -->
<el-table-column type="expand">
  <template slot-scope="scope">
    <el-row
      :class="['bdbottom', i1 === 0 ? 'bdtop' : '']"
      v-for="(item1, i1) in scope.row.children"
      :key="item1.id"
    >
      <!-- 渲染一级权限 -->
      <el-col :span="5">
        <el-tag>{{ item1.authName }}</el-tag>
        <i class="el-icon-caret-right"></i>
      </el-col>
      <!-- 渲染二级和三级权限 -->
      <el-col :span="19"></el-col>
    </el-row>
  </template>
</el-table-column>
  • 样式
<style lang="less" scoped>
.el-tag {
  margin: 7px;
}

.bdtop {
  border-top: 1px solid #eee;
}

.bdbottom {
  border-bottom: 1px solid #eee;
}
</style>

在这里插入图片描述

2.4 渲染二级和三级权限

  <!-- 渲染二级和三级权限 -->
  <el-col :span="19">
    <!-- 二级 -->
    <el-row
      :class="[i2 === 0 ? '' : 'bdtop']"
      v-for="(item2, i2) in item1.children"
      :key="item2.id"
    >
      <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>

在这里插入图片描述

2.5 美化角色下权限的UI结构

  • 全局设置页面最小宽度

解决页面过窄时,页面变形

/* 全局样式表 */
html,
body,
#app {
  ...
  min-width: 1366px; /* 防止页面过窄导致的页面变形,定义最小宽度为1366像素 */
}
  • 设置一,二级tag居中
    定义样式
.vcenter{
    display: flex;
    align-items: center;
}

绑定样式

<el-row
  :class="['bdbottom', i1 === 0 ? 'bdtop' : '','vcenter']"
  v-for="(item1, i1) in scope.row.children"
  :key="item1.id"
>
<!-- 二级 -->
<el-row
  :class="[i2 === 0 ? '' : 'bdtop','vcenter']"
  v-for="(item2, i2) in item1.children"
  :key="item2.id"
>

在这里插入图片描述

2.6 完成删除角色下指定权限的功能

  • 绑定删除方法
  <!-- 渲染一级权限 -->
  <el-col :span="5">
    <el-tag closable
    @close="removeRightById(scope.row, item1.id)">{{ item1.authName }}</el-tag>
    <i class="el-icon-caret-right"></i>
  </el-col>
  <!-- 渲染二级和三级权限 -->
  <el-col :span="19">
    <!-- 二级 -->
    <el-row
      :class="[i2 === 0 ? '' : 'bdtop', 'vcenter']"
      v-for="(item2, i2) in item1.children"
      :key="item2.id"
    >
      <el-col :span="6">
        <el-tag
          type="success"
          closable
          @close="removeRightById(scope.row, item2.id)"
          >{{ 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"
          closable
          @close="removeRightById(scope.row, item3.id)"
          >{{ item3.authName }}</el-tag
        >
      </el-col>
  • 实现删除方法
// 删除角色制定权限
async removeRightById(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("删除权限失败!");
  }

  // 将接口数据中的data直接赋值给children,防止页面过渡刷新
  role.children = res.data;
},

3 分配权限

3.1 弹出分配权限对话框并请求权限数据

  • 分配权限按钮绑定点击事件showSetRightDialog,并实权限列表的数据获取:
async showSetRightDialog() {
  const { data: res } = await this.$http.get("rights/tree");
  if (res.meta.status !== 200) {
    return this.$message.error("获取权限列表失败!");
  }
  this.rightsList = res.data;
  console.log(this.rightsList);
  this.setRightDialogVisible = true;
},
  • 编写弹窗
<!-- 分配权限对话框 -->
<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>

3.2 配置并使用el-tree树形控件

使用element-ui中的[tree树形控件](https://element.eleme.cn/#/zh-CN/component/tree)来展示权限列表数据。

属性show-checkbox:节点是否可被选择
属性render-after-expand:是否在第一次展开某个树节点后才渲染其子节点
属性node-key: 每个树节点用来作为唯一标识的属性,整棵树应该是唯一的

 <el-tree
    :data="rightsList"
    :props="treeProps"
    show-checkbox
    default-expand-all
    node-key="id"
 ></el-tree>
// 树形控件的属性绑定对象
treeProps: {
    children: "children",
    label: "authName",
},

在这里插入图片描述

3.3 加载当前角色已有的权限

在展开角色的权限弹窗时,需要将对应的权限

  • 树形控件加上default-checked-keys属性,展示默认选中的项
<!-- 分配权限对话框 -->
<el-dialog
  title="分配权限"
  :visible.sync="setRightDialogVisible"
  width="50%"
  @close="closeRightDialog()"
>
  <!-- 树形控件 -->
  <el-tree
    :data="rightsList"
    :props="treeProps"
    show-checkbox
    default-expand-all
    node-key="id"
    :default-checked-keys="defKeys"
  ></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>
  • 完成递归获取id的方法
// 通过递归的形式,获取角色下所有三级权限的id,并保存到 defkeys数组中
getLeafKeys(node, arr) {
  // 如果当前mode节点不包含children属性,则是三级节点
  if (!node.children) {
    return arr.push(node.id);
  }

  node.children.forEach((item) => {
    this.getLeafKeys(item, arr);
  });
},
  • 调用递归函数
// 展示分配权限的对话框
async showSetRightDialog(role) {
  // 通过接口获取所有的权限列表
  const { data: res } = await this.$http.get("rights/tree");
  if (res.meta.status !== 200) {
    return this.$message.error("获取权限列表失败!");
  }
  this.rightsList = res.data;

  // 获取该角色已有权限的id
  this.getLeafKeys(role, this.defKeys);
  this.setRightDialogVisible = true;
},
  • 关闭弹窗时清空默认展示列表
closeRightDialog() {
  this.defKeys = [];
},

3.4 调用API完成分配权限的功能

  • 给树形结构绑定ref属性,并给弹窗的确定按钮,绑定allotRights()方法
<el-tree
    :data="rightsList"
    :props="treeProps"
    show-checkbox
    default-expand-all
    node-key="id"
    :default-checked-keys="defKeys"
    ref="treeRef"
></el-tree>
  • 实现allotRights()方法:
    • 通过角色授权(roles/:roleId/rights)接口来给用户分配相关权限。
    • 该接口的post传参需要传递权限 ID 列表
    • 通过树形结构的方法getCheckedNodes()getHalfCheckedKeys()来获取选中和半选中的权限的id。

知识点:
1、ref属性:ref 被用来给DOM元素或子组件注册引用信息。引用信息会根据父组件的 $refs 对象进行注册。如果在普通的DOM元素上使用,引用信息就是元素; 如果用在子组件上,引用信息就是组件实例。(注意:只要想要在Vue中直接操作DOM元素,就必须用ref属性进行注册)
2、getCheckedKeys:若节点可被选择(即 show-checkbox 为 true),则返回目前被选中的节点所组成的数组。
3、getHalfCheckedKeys:若节点可被选择(即 show-checkbox 为 true),则返回目前被选中的节点的 key 所组成的数组。

// 点击为角色分配权限
async allotRights() {
  // 获取树形结构选中的id,并转换成字符串(给接口传参)
  const keys = [
    ...this.$refs.treeRef.getCheckedKeys(),
    ...this.$refs.treeRef.getHalfCheckedKeys(),
  ];
  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;
},

分配角色

完成用户列表操作栏的分配角色的功能

  • 定义变量
// 控制分配角色弹窗
setRoleDialogVisible: false,
// 需要被分配角色的用户信息
userInfo: {},
// 所有角色的数据列表
rolesList: [],
// 已选中的角色ID值
selectRoleId: "",
  • 分配按钮绑定setRole方法,实现点击后,获取角色列表信息,并且展示出来弹框
// 分配角色
async setRole(userInfo) {
  this.userInfo = userInfo;

  // 获取角色列表
  const { data: res } = await this.$http.get("roles");
  if (res.meta.status !== 200) {
    return this.$message.error("获取角色列表失败!");
  }

  this.rolesList = res.data;

  this.setRoleDialogVisible = true;
},
  • 完成分配角色弹窗绘制

知识点:
select控件循环展示数据

<!-- 分配角色弹窗 -->
<el-dialog
  title="提示"
  :visible.sync="setRoleDialogVisible"
  width="50%"
  @close="setRoleDialogClosed()"
>
  <div>
    <p>当前的用户:{{ userInfo.username }}</p>
    <p>当前的角色:{{ userInfo.role_name }}</p>
    <p>
      分配新角色:
      <el-select v-model="selectRoleId" placeholder="请选择">
        <el-option
          v-for="item in rolesList"
          :key="item.id"
          :label="item.roleName"
          :value="item.id"
        >
        </el-option>
      </el-select>
    </p>
  </div>
  <span slot="footer" class="dialog-footer">
    <el-button @click="setRoleDialogVisible = false">取 消</el-button>
    <el-button type="primary" @click="saveRoleInfo()">确 定</el-button>
  </span>
</el-dialog>

在这里插入图片描述

  • 实现在点击分配角色弹窗的确定按钮后,设置该用户的角色
// 保存用户的角色信息
async saveRoleInfo() {
  if (!this.selectRoleId) {
    return this.$message.error("请选择角色!");
  }

  const { data: res } = await this.$http.put(
    `users/${this.userInfo.id}/role`,
    {
      rid: this.selectRoleId,
    }
  );
  if (res.meta.status !== 200) {
    return this.$message.error("分配角色失败!");
  }

  this.getUserList();
  this.setRoleDialogVisible = false;
},
  • 实现关闭弹窗时,重置数据
// 监听分配角色对话框的关闭事件
setRoleDialogClosed() {
  this.selectRoleId = "";
  this.userInfo = {};
},
  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2021-07-26 11:59:24  更:2021-07-26 12:01:46 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年4日历 -2024/4/25 22:34:57-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码