vue以前端鉴权

  vue项目前端鉴权方式经常使用的有如下三种:html

    一、渲染菜单时控制模块按钮的显示隐藏(不足:直接输入连接仍然能够访问模块前端

    二、在路由导航守卫中拦截,针对没有权限的模块进行重定向(不足:每次访问模块都须要鉴定权限,模块数量过多时会影响系统性能vue

    三、借助vue-router 2.x版本新加的API addRouters动态添加路由信息(不足:首次加载须要解析和添加,多跳转一次路由node

  综上所述,权衡以后选择了addRoutes动态添加,首屏加载时间可能会多出0.5s左右,加载一次以后后续就不须要再进行处理,能够提高系统的可靠性与稳定性。具体使用以下:vue-router

    一、定义固定路由,用于路由初始化,如:登陆页、404页面等vuex

const router = new Router({ // mode: 'history',
    // base: base,
 routes: [ { path: '/', name: '', component: () => import('@/views/login/login') , meta:{label: '登陆'} } ], scrollBehavior(to, from, savedPosition) { if (savedPosition) { return savedPosition } else { return { x: 0, y: 0 } } } }); 

    二、路由导航守卫前置拦截后端

      为了方便,将路由权限信息保存到vuex中,在路由跳转时,判断state中是否存在menu信息,若是不存在,则向后端请求权限信息,此部分须要阻塞页面的跳转,改成同步执行;async

      针对通常菜单嵌套路由,须要对路由信息最好进行扁平化处理,不然可能致使路由重复添加或者添加失败(上级有父组件会致使重复添加,上级没有组件单纯嵌套会致使添加失败)性能

//刷新页面后,会致使动态生成的路由失效,须要从新走下添加路由操做
let registerRouteRefresh = true; router.beforeEach(async (to, from, next) => { //若是不存在菜单信息,则走动态受权
    if (store.state.menus.length === 0) { //确保初始化信息完成后才会执行下一步动做
 await init(); let nodesList = []; //递归获取权限菜单列表
 initNodes(menuNodes, nodesList); store.commit('UPDATE_DATA', { key: 'menus', value: nodesList }); //获取路由权限信息
        const asyncNodes = getAsyncNodes(nodesList, []); //添加拥有权限的路由信息
 router.addRoutes(asyncNodes); registerRouteRefresh = false; next({ ...to, replace: true }) }else { //若是是页面刷新,须要从新加载下动态路由
        if (registerRouteRefresh) { let nodesList = []; //递归获取权限菜单列表
 initNodes(menuNodes, nodesList); //获取路由权限信息
            const asyncNodes = getAsyncNodes(nodesList, []); //添加拥有权限的路由信息
 router.addRoutes(asyncNodes); registerRouteRefresh = false; //确保路由加载完成
 next({ ...to, replace: true }) } next() } });

  注意spa

    一、因为路由时动态添加的,存储在内存中,页面刷新以后内存中变量也会消失,动态添加的路由也会随之消失,因此每次刷新页面须要从新走一遍添加路由的流程

    二、因为路由是动态添加的,在路由跳转时,添加的路由并无生效,因此还须要多跳转一次页面

  除此以外,按钮的鉴权能够经过自定义指令,动态传入条件参数来实现按钮的显示隐藏,指令封装以下:

/** * 节点鉴权 * {code: menuCode, flag:条件生效取反} */ Vue.directive('permission', { bind(el, binding) { let vv = binding.value; if (vv.flag) { el.style.display = hasPermission(vv.code) ? 'none' : 'block'; } else { el.style.display = hasPermission(vv.code) ? 'block' : 'none'; } } });

  使用方法:

<button v-permission="{code: 123}"></button >

 

      

原文出处:https://www.cnblogs.com/gerry2019/p/11045555.html

相关文章
相关标签/搜索