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>

总结

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

相关推荐
碎碎念_4924 小时前
SpringBoot + Vue 前后端分离从 0 到 1 完整环境配置流程
vue.js·spring boot·后端
shuaijie05185 小时前
强制修改调用接口的api地址。
javascript·vue.js·ecmascript
JerrySir5 小时前
恶意 npm 包只活了 17 分钟:技术面试里,为什么“升级依赖”还不算止血?
javascript·安全
白帽小阳5 小时前
2026前端面试题!(附答案及解析)
javascript·网络·python·安全·web安全·网络安全·护网行动
这是个栗子5 小时前
前端开发中的常用工具函数(八)
开发语言·前端·javascript
Hilaku5 小时前
Vue 和 React 真正的差距,不在语法,而在团队犯错成本
前端·javascript·程序员
研☆香5 小时前
为什么变量声明在赋值前也能使用?—— 深入理解 JavaScript 变量提升与作用域
开发语言·前端·javascript
柯克七七6 小时前
我把 bug 修得太干净了,测试组以为这个模块本来就没问题
前端·javascript·typescript
Null1556 小时前
浏览器唤起桌面端应用(终极篇)
前端·javascript
妙码生花6 小时前
从 PHP 到 AI + Golang,程序员自救转型手记(三十四):后台初始化请求实现
前端·javascript·go