Vue组件级权限控制

前言

在WEB应用开发过程中,权限控制是保证数据安全和用户体验的关键部分。通常,权限控制分为两个等级:页面级和组件级。

  • 页面级根据不同用户身份渲染不同路由,用于确定用户是否能访问整个应用程序或特定功能,例如访客和管理员有着不同的权限。
  • 组件级根据不同用户权限渲染具体组件或决定该组件是否允许某些操作,例如操作删除,访问详细信息等。

本文专注于讨论组件级权限控制,这一技术允许我们对每个具体的组件和页面进行精确的权限管理,确保用户只能访问其被授权的数据,隐藏不必要的元素,从而提升数据安全性和用户体验。

案例

在本案例中,我们定义了两个角色:管理员(admin)和访客(visitor)。管理员具备预览、添加、编辑和删除的全部权限,而访客仅具备预览权限。

定义权限

变量 permission 包含了访客(visitor)角色和管理员(admin)角色所拥有的权限集合。

javascript 复制代码
// permission.js
const permission = {
  visitor: ["view"],
  admin: ["create", "delete", "edit", "view"],
};

定义store

在此示例中,我们创建了一个用户权限的存储(store)。初始情况下,我们默认用户角色为访客(visitor),并为其分配了与访客角色相关的权限。此外,我们还定义了 changeRole 方法,以便外部可以轻松地更改用户的角色。这个机制允许模拟不同用户角色的权限变化,以便更好地测试和验证组件级权限控制的效果。

javascript 复制代码
import permission from "../config/permission";
import { defineStore } from "pinia";

export default defineStore("user", {
  state: () => ({
    // 用户角色
    role: "visitor",
    // 用户权限
    permissions: permission.visitor,
  }),
  actions: {
    // 切换角色
    changeRole(role) {
      this.role = role;
      this.permissions = permission[role];
    },
  },
});

自定义Authority组件

我们通过一个自定义的Vue组件示例来说明组件级权限控制的实际应用。我们将使用一个名为 Authority 的组件,该组件根据用户的权限来决定是否渲染其包含的内容。

【主要实现】

  • 通过visible 变量:动态决定组件的可见性
  • 传入的permission 参数具备多种用法。
  1. 当不传或传入空值时,表示无需任何权限即可访问。
  2. 如果传入单个权限时,系统将检查用户角色是否包含该权限,如果包含则显示,否则隐藏。
  3. 当传入权限集合时,只要用户角色拥有的权限包含在集合中,就会显示,否则将被隐藏。
javascript 复制代码
<template>
  <slot v-if="visible"></slot>
</template>

<script setup>
import useUserStore from "../store/user";
import { computed, defineProps } from "vue";

const useStore = useUserStore();
const props = defineProps({
  permission: {
    // 支持单个或多个权限
    type: [String, Array],
    value: "",
  },
});

const visible = computed(() => {
  const { permissions } = useStore;
  const { permission } = props;
  if (!permission) {
    // 无需权限
    return true;
  }
  if (!permissions) {
    // 用户无权限
    return false;
  }

  if (Array.isArray(permission)) {
    // 多个权限
    return permission.some((i) => permissions.includes(i));
  } else {
    // 单个权限
    return permissions.includes(permission);
  }
});
</script>

<style scoped></style>

如何使用 Authority 组件

在我们的示例中,我们使用了 Authority 组件来管理页面上的操作按钮,例如"预览"、"添加"、"编辑"和"删除"。每个按钮都有一个 permission 属性,该属性指定了用户需要具备的权限才能看到和使用该按钮。

javascript 复制代码
<template>
  <main class="main">
    <section class="role">
      <label>切换角色:</label>
      <el-select
        placeholder="请选择角色"
        :modelValue="userStore.role"
        @change="onRoleChange"
      >
        <el-option
          v-for="role in roleOptions"
          :key="role.value"
          :label="role.name"
          :value="role.value"
        />
      </el-select>
    </section>
    <section>
      <el-space>
        <Authority permission="view">
          <el-button>预览</el-button>
        </Authority>
        <Authority permission="create">
          <el-button type="primary">添加</el-button>
        </Authority>
        <Authority permission="edit">
          <el-button type="success">编辑</el-button>
        </Authority>
        <Authority :permission="['delete']">
          <el-button type="danger">删除</el-button>
        </Authority>
      </el-space>
    </section>
  </main>
</template>

<script setup>
import Authority from "./components/Authority.vue";
import { ref } from "vue";
import useUserStore from "./store/user";

const userStore = useUserStore();

const roleOptions = ref([
  { name: "admin", value: "admin" },
  { name: "visitor", value: "visitor" },
]);

const onRoleChange = (role) => {
  userStore.changeRole(role);
};
</script>

<style>
.role {
  margin-bottom: 160px;
}
</style>

总结

组件级权限控制是提高前端安全性和用户体验的强大工具。通过动态渲染页面上的不同组件和元素,以及根据用户的权限隐藏或显示操作按钮,确保用户只能访问和操作他们有权访问的内容。这不仅增强了应用程序的安全性,还提高了用户的满意度和体验。无论应用程序规模如何,组件级权限控制都是一个值得考虑的实现方案,有助于确保应用程序的数据和功能受到良好的保护。

相关推荐
binqian31 分钟前
【异步】js中异步的实现方式 async await /Promise / Generator
开发语言·前端·javascript
LIUENG1 小时前
Vue3 响应式原理
前端·vue.js
前端李二牛1 小时前
异步任务并发控制
前端·javascript
你也向往长安城吗1 小时前
推荐一个三维导航库:three-pathfinding-3d
javascript·算法
karrigan2 小时前
async/await 的优雅外衣下:Generator 的核心原理与 JavaScript 执行引擎的精细管理
javascript
wycode2 小时前
Vue2实践(3)之用component做一个动态表单(二)
前端·javascript·vue.js
wycode3 小时前
Vue2实践(2)之用component做一个动态表单(一)
前端·javascript·vue.js
第七种黄昏3 小时前
Vue3 中的 ref、模板引用和 defineExpose 详解
前端·javascript·vue.js
我是哈哈hh3 小时前
【Node.js】ECMAScript标准 以及 npm安装
开发语言·前端·javascript·node.js
张元清4 小时前
电商 Feeds 流缓存策略:Temu vs 拼多多的技术选择
前端·javascript·面试