「从零开始的 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的个人理解,如有不足之处,欢迎大家指正与交流,共同进步。
相关推荐
vener_1 分钟前
LuckySheet协同编辑后端示例(Django+Channel,Websocket通信)
javascript·后端·python·websocket·django·luckysheet
草字7 分钟前
uniapp input限制输入负数,以及保留小数点两位.
java·前端·uni-app
老码沉思录13 分钟前
React Native 全栈开发实战班 - 性能与调试之打包与发布
javascript·react native·react.js
没有黑科技26 分钟前
基于web的音乐网站(Java+SpringBoot+Mysql)
java·前端·spring boot
计算机毕设孵化场27 分钟前
计算机毕设-基于springboot的多彩吉安红色旅游网站的设计与实现(附源码+lw+ppt+开题报告)
vue.js·spring boot·后端·计算机外设·课程设计·计算机毕设论文·多彩吉安红色旅游网站
前端初见36 分钟前
彻底搞懂前端环境变量使用和原理
前端
小王码农记1 小时前
vue中路由缓存
前端·vue.js·缓存·typescript·anti-design-vue
战神刘玉栋1 小时前
《SpringBoot、Vue 组装exe与套壳保姆级教学》
vue.js·spring boot·后端
大G哥1 小时前
我用豆包MarsCode IDE 做了一个 CSS 权重小组件
前端·css
乐闻x1 小时前
Vue实践篇:如何在 Vue 项目中检测元素是否展示
前端·javascript·vue.js