一文搞懂admin后台路由权限实现,按钮权限控制。

4,020 阅读3分钟

我正在参加 「掘金日新计划 · 4 月更文挑战」,今天要讲的是路由权限以及指令权限(按钮级别的权限)的实现原理。

路由权限

在Vue admin manage的后台管理系统中,通常需要实现动态路由,以便根据用户权限动态生成菜单和路由。以下是实现动态路由的一般步骤

在路由配置中定义动态路由

在Vue的路由配置中,可以定义动态路由,例如:

const routes = [
  {
    path: '/',
    name: 'Dashboard',
    component: Dashboard,
    meta: { requiresAuth: true }
  },
  {
    path: '/users',
    name: 'Users',
    component: Users,
    meta: { requiresAuth: true, requiresAdmin: true }
  },
  {
    path: '/products',
    name: 'Products',
    component: Products,
    meta: { requiresAuth: true }
  },
  // ...
]

上面的代码中,每个路由都有一个meta属性,用于存储路由的元数据。其中,requiresAuth表示该路由需要用户登录后才能访问,requiresAdmin表示该路由需要管理员权限才能访问。

在路由守卫中根据权限动态生成路由

在Vue的路由导航守卫中,可以根据用户权限动态生成路由和菜单。例如:

router.beforeEach((to, from, next) => {
  // 判断用户是否已经登录
  const isAuthenticated = store.getters.isAuthenticated;
  if (to.matched.some(record => record.meta.requiresAuth)) {
    if (!isAuthenticated) {
      // 如果用户未登录,则跳转到登录页
      next({ name: 'Login' });
    } else {
      // 根据用户权限动态生成路由
      const userPermissions = store.getters.userPermissions;
      const routes = generateRoutes(userPermissions);
      router.addRoutes(routes);
      next();
    }
  } else {
    next('/403') // 如果权限不足,则跳转到 403 页面
  }
})

function generateRoutes(userPermissions) {
  const routes = [];
  // 根据用户权限动态生成路由
  if (userPermissions.indexOf('admin') !== -1) {
    routes.push({
      path: '/admin',
      name: 'Admin',
      component: Admin,
      meta: { requiresAuth: true, requiresAdmin: true }
    });
  }
  // ...
  return routes;
}

上面的代码中,beforeEach路由守卫会在每次路由跳转前执行。如果to路由需要用户登录才能访问,则判断用户是否已经登录。如果已经登录,则根据用户权限动态生成路由,并通过router.addRoutes()方法动态添加路由。最后调用next()方法,继续路由跳转。

admin 超管权限 可以访问所有路由,editor编辑权限 onlyRead 只读权限

可实现具体效果图如下:

image.png

image.png

在菜单组件中根据路由生成菜单

在Vue的菜单组件中,可以根据路由动态生成菜单。例如:

<template>
  <ul>
    <li v-for="route in routes" :key="route.name">
      <router-link :to="route.path">{{ route.name }}</router-link>
      <ul v-if="route.children">
        <menu :routes="route.children"></menu>
      </ul>
    </li>
  </ul>
</template>

<script>
export default {
  name: 'Menu',
  props: {
    routes: {
      type: Array,
      required: true
    }
  },
  computed: {
    filteredRoutes() {
      return this.routes.filter(route => {
        return route.meta && route.meta.requiresAuth;
      })
    }
  }
}
</script>

上面的代码中,Menu组件根据传入的routes属性动态生成菜单。如果路由有子路由,则递归调用Menu组件生成子菜单。

通过上述步骤,就可以实现基于动态路由的后台管理系统了。

自定义指令来实现权限控制

在Vue中,可以通过自定义指令来实现权限控制。又被称为按钮级别的权限控制实现。具体步骤如下:

定义自定义指令

可以使用Vue.directive()方法来定义自定义指令。例如:

Vue.directive('permission', {
  inserted: function (el, binding) {
    // 根据用户权限来决定是否显示元素
    if (!checkPermission(binding.value)) {
      el.parentNode.removeChild(el);
    }
  }
})

上面的代码定义了一个名为permission的指令,实际可以根据需求命名,如你需要一个仅可以编辑的可以命名为 check-editor 等。具体情况具体分析,这里要说明一下,它会在元素插入到DOM中时执行inserted函数。在该函数中,根据用户权限来判断是否显示元素。

在模板中使用自定义指令

在模板中使用自定义指令时,只需要将指令名作为元素的属性即可。例如:

<button v-permission="'edit'">编辑</button>

上面的代码中,v-permission指令的值为'edit',表示只有拥有编辑权限的用户才能看到该按钮。

checkPermission函数的实现

checkPermission函数主要是用来判断当前用户是否拥有某项权限的函数。它可以从服务端获取用户信息,亦或者从本地存储中读取用户权限信息。例如:

function checkPermission(permission) {
 const roles = store.getters && store.getters.roles
  if (roles.indexOf(permission) !== -1) {
    return true;
  } else {
    return false;
  }
}

上面的代码中,checkPermission函数从token中读取用户权限信息,判断是否拥有指定权限。当然也可以使用本地存储来读取实现用户权限信息

综上所述步骤,就可以实现基于自定义指令的权限控制了。

可实现具体效果图如下:

image.png

image.png