「从零开始的 Vue 3 系列」:第九章——vue3中实‘动态路由‘与“权限管理“

前言

本系列将从零开始,系统性地介绍 Vue 3 的常用 API,逐步深入每个核心概念与功能模块。通过详尽的讲解与实战演示,帮助大家掌握 Vue 3 的基础与进阶知识,最终具备独立搭建完整 Vue 3 项目的能力。

**思路:**动态路由实现就是前端登录获取用户信息->后端验证与权限获取->返回权限数据->前端动态生成路由-->权限控制

那么项目中是如何实现呢:

定义基础路由

cpp 复制代码
import { createRouter, createWebHistory } from 'vue-router';

const routes = [
  { path: '/', component: Home },
  { path: '/login', component: Login },
  // 其他公共路由
];

const router = createRouter({
  history: createWebHistory(),
  routes,
});

export default router;

在用户登录时,从后端获取用户的权限数据。权限数据通常包含用户可以访问的路由或角色信息。

动态路由与菜单权限:

动态添加路由(一般是菜单权限):

根据从后端获取的权限数据,使用 Vue Router 的 addRoute 方法动态添加路由。例如:

方法一般都要挂在到main.js中,可以将动态路由方法写到新建的js中,然后将这个js引入进main.js

cpp 复制代码
function addDynamicRoutes(permissions) {
  const dynamicRoutes = permissions.map(permission => {
    return {
      path: permission.path,
      component: () => import(`../views/${permission.component}`),
    };
  });

  dynamicRoutes.forEach(route => {
  	//这里使用addRoute添加到路由
    router.addRoute(route);
  });
}

设置路由守卫:

使用路由守卫(如 beforeEach)来验证用户是否有权限访问某个路由。如果没有权限,可以重定向到登录页面或错误页面。

cpp 复制代码
router.beforeEach((to, from, next) => {
  const isAuthenticated = // 判断用户是否已认证
  const hasPermission = // 判断用户是否有访问该路由的权限

  if (!isAuthenticated && to.path !== '/login') {
    next('/login');
  } else if (isAuthenticated && !hasPermission) {
    next('/403'); // 无权限页面
  } else {
    next();
  }
});

按钮权限:

1.基于指令的权限控制

你可以创建自定义指令来控制按钮的显示或禁用,这样可以在模板中方便地使用。

cpp 复制代码
const app = Vue.createApp({});

app.directive('permission', {
  mounted(el, binding) {
    const userPermissions = binding.instance.$data.userPermissions; // 假设从组件实例中获取用户权限
    if (!userPermissions.includes(binding.value)) {
      el.style.display = 'none'; // 隐藏没有权限的按钮
    }
  }
});

app.component('my-component', {
  data() {
    return {
      userPermissions: ['view', 'edit'] // 用户权限示例
    };
  },
  template: `
    <button v-permission="'edit'">Edit</button>
    <button v-permission="'delete'">Delete</button>
  `
});

app.mount('#app');

2.使用 Vuex 进行权限管理

在更复杂的应用中,可能需要使用 Vuex 来集中管理用户权限,并在组件中获取权限状态。

cpp 复制代码
const store = Vuex.createStore({
  state() {
    return {
      userPermissions: ['view', 'edit']
    };
  },
  getters: {
    hasPermission: (state) => (permission) => {
      return state.userPermissions.includes(permission);
    }
  }
});

const app = Vue.createApp({
  computed: {
    canEdit() {
      return this.$store.getters.hasPermission('edit');
    },
    canDelete() {
      return this.$store.getters.hasPermission('delete');
    }
  },
  template: `
    <button v-if="canEdit">Edit</button>
    <button v-if="canDelete">Delete</button>
  `
});

app.use(store).mount('#app');

3.使用计算属性或方法

在模板中使用计算属性或方法来决定按钮是否显示或禁用。

cpp 复制代码
const app = Vue.createApp({
  data() {
    return {
      userPermissions: ['view', 'edit'] // 用户权限示例
    };
  },
  methods: {
    hasPermission(permission) {
      return this.userPermissions.includes(permission);
    }
  },
  template: `
    <button v-if="hasPermission('edit')">Edit</button>
    <button v-if="hasPermission('delete')">Delete</button>
  `
});

app.mount('#app');

4.基于组件封装

你可以创建一个权限按钮组件,内部包含权限逻辑,方便在应用中多次复用。

cpp 复制代码
app.component('permission-button', {
  props: ['permission'],
  template: `
    <button v-if="hasPermission">{{ permission }}</button>
  `,
  computed: {
    hasPermission() {
      return this.$root.userPermissions.includes(this.permission); // 假设从根实例获取用户权限
    }
  }
});

// 在根实例中定义用户权限
const app = Vue.createApp({
  data() {
    return {
      userPermissions: ['view', 'edit']
    };
  },
  template: `
    <permission-button permission="edit"></permission-button>
    <permission-button permission="delete"></permission-button>
  `
});

app.mount('#app');

总结:根据应用的复杂程度,你可以选择以上不同的方法来实现按钮权限控制。对于简单的权限检查,自定义指令或计算属性可能就足够了;而对于复杂的权限系统,可以考虑使用 Vuex 或封装组件的方式。这样不仅可以提高代码的可维护性,还可以保持代码的可读性和复用性。

ps:以上内容仅为本人对 vue3的个人理解,如有不足之处,欢迎大家指正与交流,共同进步。
相关推荐
程序员Sunday8 小时前
JavaScript 事件循环面试题,宏任务与微任务怎么执行|Sunday面试指南
开发语言·javascript·面试·校招·事件循环·程序员sunday
Setsuna_F_Seiei8 小时前
前端转型 Agent 开发 06 之 Agent Memory 记忆系统(让 Agent 更智能,更懂你)
前端·agent·ai编程
志尊宝9 小时前
Vue3 零基础每日笔记(073):keep-alive 页面缓存实战——列表页返回不丢状态
vue.js·笔记·缓存·#vue #前端 #前端开发·#javascript·#vue.js
zhangzeyuaaa9 小时前
Ruby 多线程、GVL(GIL)与 Mutex 完全指南
开发语言·前端·ruby
默_笙9 小时前
🌊 向量库和 ES 都查不出"关系",我只好给奶茶建了一张人脉网
前端·javascript
优选资讯9 小时前
标签打印软件怎么对接 Excel 数据
前端·excel
思无邪6610 小时前
用 AI 做 JS 逆向:从抓包到复现的完整方法论
开发语言·javascript·人工智能
一个风轻云淡10 小时前
GCC 和 GDB命令简单解读
java·linux·前端
u01110267511 小时前
图片处理接口如何统一错误信息 前端提示与后端错误码设计
前端·状态模式
福兮说12 小时前
浏览器里把 iPhone 的 HEIC 转成 JPG:Chrome 解不开、转完大了七成、拍摄时间全丢,六个坑实测
前端·javascript·图像处理·chrome·ios·iphone·heic