最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

vue2模擬vue-element-admin手寫(xiě)角色權(quán)限的實(shí)現(xiàn)

 更新時(shí)間:2022年07月13日 11:18:38   作者:TomorrowLM  
本文主要介紹了vue2模擬vue-element-admin手寫(xiě)角色權(quán)限的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

權(quán)限

路由權(quán)限

  • 靜態(tài)路由:固定的路由,沒(méi)有權(quán)限。如login頁(yè)面
  • 動(dòng)態(tài)路由:根據(jù)不同的角色,后端返回不同的路由接口。通過(guò)meta中的roles去做篩選

store存儲(chǔ)路由

//地址:store/modules/permission
import { routes as constantRoutes } from '@/router'
?
// 根據(jù)meta.roles去判斷該角色是否有路由權(quán)限
function hasPermission(roles, route) {
  if (route.meta && route.meta.roles) {
    return route.meta.roles.some(val => val === roles)
  }
  return true
}
?
/**
 * 遞歸動(dòng)態(tài)路由
 * @param routes 動(dòng)態(tài)路由
 * @param roles 角色
 */
export function filterAsyncRoutes(routes, roles) {
  const res = []
  routes.forEach(route => {
    const tmp = { ...route }
    if (hasPermission(roles, tmp)) {
      if (tmp.children) {
        //后臺(tái)傳來(lái)的路由字符串,轉(zhuǎn)換為組件對(duì)象
        //       let a = `../views/${route.component}`;
        //       route.component = () => import(a); // 導(dǎo)入組件
        tmp.children = filterAsyncRoutes(tmp.children, roles)
      }
      res.push(tmp)
    }
  })
?
  return res
}
?
//模擬后端傳過(guò)來(lái)的路由
export const asyncRoutes = [
  {
    path: '/',
    name: 'home',
    redirect: '/PickupTask',
    meta: {
      title: '首頁(yè)',
      //純前端去做動(dòng)態(tài)路由
      roles: ['admin']
    },
    component: () => import('@/views/HomeView.vue'),
    children: [
      {
        path: 'PickupTask',
        name: 'PickupTask',
        meta: {
          title: 'PickupTask',
        },
        component: () => import('@/views/Sd/PickupTask.vue'),
      },
      {
        path: 'access',
        hidden: true,
        component: () => import('@/views/demo/Access.vue'),
        meta: {
          title: 'access',
          roles: ['admin'],
          //按鈕權(quán)限標(biāo)識(shí)
          button: {
            'btn:access:createUser': 'hidden',
            'btn:access:editUser': 'disable'
          },
        },
      },
    ],
  }
]
?
const permisssion = {
  // namespaced: true, -> store.dispatch('permisssion/generateRoutes', 'admin');
  state: {
    //靜態(tài)路由+動(dòng)態(tài)路由
    routes: [],
    //動(dòng)態(tài)路由
    addRoutes: []
  },
  mutations: {
    SET_ROUTES: (state, routes) => {
      state.addRoutes = routes
      state.routes = constantRoutes.concat(routes)
    }
  },
  actions: {
    generateRoutes({ commit }, roles) {
      return new Promise(resolve => {
        let accessedRoutes = filterAsyncRoutes(asyncRoutes, roles)
        commit('SET_ROUTES', accessedRoutes)
        resolve(accessedRoutes)
      })
    }
  }
}
?
export default permisssion

router添加路由

將store中的動(dòng)態(tài)路由使用addRoute添加(最新版本去掉了addRoutes只能使用addRoute添加路由)。

//地址:router/index
import Vue from 'vue';
import VueRouter, { RouteConfig } from 'vue-router';
import store from '@/store';
?
Vue.use(VueRouter);
?
const isProd = process.env.NODE_ENV === 'production';
const routerContext = require.context('./', true, /index.js$/);
//靜態(tài)路由
export let routes: any = [];
?
routerContext.keys().forEach((route) => {
  // route就是路徑
  // 如果是根目錄的index不做處理
  if (route.startsWith('./index')) {
    return;
  }
  const routerModule = routerContext(route);
  routes = [...routes, ...(routerModule.default || routerModule)];
});
?
// 創(chuàng)建 router 實(shí)例,然后傳 `routes` 配置
const router = new VueRouter({
  mode: 'history',
  base: isProd ? '/vue-demo/' : process.env.BASE_URL,
  routes,
  scrollBehavior(to, from, savedPosition) {
    if (to.hash) {
      return {
        selector: to.hash,
      };
    }
  },
});
?
let registerRouteFresh = true;
/**
 * 全局全局前置守衛(wèi)
 * to : 將要進(jìn)入的目標(biāo)路由對(duì)象
 * from : 即將離開(kāi)的目標(biāo)路由對(duì)象
 */
router.beforeEach(async (to: any, from, next) => {
  //設(shè)置當(dāng)前頁(yè)的title
  document.title = to.meta.title;
  if (to.path === '/login' && localStorage.getItem('token')) {
    next('/');
  }
  console.log(registerRouteFresh);
  //如果首次或者刷新界面,next(...to, replace: true)會(huì)循環(huán)遍歷路由,
  //如果to找不到對(duì)應(yīng)的路由那么他會(huì)再執(zhí)行一次beforeEach((to, from, next))直到找到對(duì)應(yīng)的路由,
  //我們的問(wèn)題在于頁(yè)面刷新以后異步獲取數(shù)據(jù),直接執(zhí)行next()感覺(jué)路由添加了但是在next()之后執(zhí)行的,
  //所以我們沒(méi)法導(dǎo)航到相應(yīng)的界面。這里使用變量registerRouteFresh變量做記錄,直到找到相應(yīng)的路由以后,把值設(shè)置為false然后走else執(zhí)行next(),整個(gè)流程就走完了,路由也就添加完了。
  if (registerRouteFresh) {
    //設(shè)置路由
    const accessRoutes = await store.dispatch('generateRoutes', 'admin');
    let errorPage = {
      path: '*',
      name: '404',
      component: () => import('../views/404.vue'),
    };
    // 將404添加進(jìn)去
    // 現(xiàn)在才添加的原因是:作為一級(jí)路由,當(dāng)刷新,動(dòng)態(tài)路由還未加載,路由就已經(jīng)做了匹配,找不到就跳到了404
    router.addRoute({ ...errorPage });
    accessRoutes.forEach((item: RouteConfig) => {
      router.addRoute(item);
    });
    //獲取路由配置
    console.log(router.getRoutes());
    //通過(guò)next({...to, replace})解決刷新后路由失效的問(wèn)題
    next({ ...to, replace: true });
    registerRouteFresh = false;
  } else {
    next();
  }
  next();
});
?
export default router;

菜單權(quán)限

路由遍歷,通過(guò)store路由權(quán)限中的permission.state.routes去做處理

按鈕權(quán)限

準(zhǔn)備:存儲(chǔ)按鈕標(biāo)識(shí)

//地址:store/modules/user
import {
  userInfo,
} from '@/api'
?
const user = {
  state: {
    role: 'admin',
    mockButton: {
      'btn:access:createUser': 'show',
      'btn:access:editUser': 'show'
    }
  },
  //更改 Vuex 的 store 中的狀態(tài)的唯一方法是提交 mutation
  mutations: {
    change_role: (state, data) => {
      state.role = data.role
    },
    change_btn: (state, data) => {
      state.mockButton = data.mockButton
    }
  },
}
?
export default user

指令

通過(guò)模擬傳入按鈕標(biāo)識(shí)的屬性,去判斷按鈕是否隱藏或者禁用

//地址:directive/permission/index
import permission from './permissionBtn'
?
const install = function(Vue) {
  Vue.directive('permission', permission)
}
?
if (window.Vue) {
  window['permission'] = permission
  Vue.use(install); // eslint-disable-line
}
?
permission.install = install
export default permission
//地址:directive/permission/permissionBtn
import store from '@/store'
?
function checkPermission(el, binding) {
  const { value } = binding
  const roles = store.getters && store.getters.role
  // 獲取模擬權(quán)限按鈕標(biāo)識(shí)
  const mockButton = store.getters && store.getters.mockButton
  // 設(shè)置按鈕屬性
  if (mockButton[value] === 'disabled') {
    el.disabled = true
    el.setAttribute('disabled', true)
  }
?
  if (mockButton[value] === 'hidden') {
    el.style.display = 'none'
  }
  if (mockButton[value] === 'show') {
    el.style.display = 'block'
    el.disabled = false
  }
  // throw new Error(`need roles! Like v-permission="['admin','editor']"`)
}
?
export default {
  inserted(el, binding) {
    checkPermission(el, binding)
  },
  update(el, binding) {
    checkPermission(el, binding)
  }
}

//應(yīng)用

<template>
  <div>
    <a-button @click="changeRole">切換角色</a-button>
    <span>當(dāng)前角色:{{ role }}</span>
    <!-- 注意一定要加disabled屬性,才能設(shè)置它的disabled值 -->
    <a-button :disabled="false" v-permission="'btn:access:createUser'">
      新建用戶(hù)
    </a-button>
    <a-button :disabled="false" v-permission="'btn:access:editUser'">
      編輯用戶(hù)
    </a-button>
  </div>
</template>
?
<script lang='ts'>
import { Vue, Component, Watch } from "vue-property-decorator";
import permission from "@/directive/permission/index.js"; // 權(quán)限判斷指令
// import checkPermission from '@/utils/permission' // 權(quán)限判斷函數(shù)
@Component({
  directives: {
    permission,
  },
  computed: {
    role() {
      return this.$store.getters.role;
    },
  },
})
export default class Access extends Vue {
  get role() {
    return this.$store.getters.role;
  }
?
  changeRole() {
    //設(shè)置按鈕權(quán)限
    this.$store.commit("change_btn", {
      mockButton:
        this.role === "admin"
          ? {
              "btn:access:createUser": "hidden",
              "btn:access:editUser": "disabled",
            }
          : {
              "btn:access:createUser": "show",
              "btn:access:editUser": "show",
            },
    });
    //設(shè)置角色
    this.$store.commit("change_role", {
      role: this.role === "admin" ? "edit" : "admin",
    });
  }
}
</script>

函數(shù)

/**
 * @param {Array} value
 * @returns {Boolean}
 * @example see @/views/permission/directive.vue
 * 除了使用指令,也可以使用函數(shù)
 */
export default function checkPermission(value) {
  if (value && value instanceof Array && value.length > 0) {
    const roles = store.getters && store.getters.roles
    const permissionRoles = value
?
    const hasPermission = roles.some(role => {
      return permissionRoles.includes(role)
    })
    return hasPermission
  }
    console.error(`need roles! Like v-permission="['admin','editor']"`)
    return false
?
}
<template>
  <div>
    <a-button
      v-if="hasPerms('btn:access:createUser')"
      :disable="hasPerms('btn:access:createUser')"
    >
      新建用戶(hù)
    </a-button>
    <a-button
      v-if="hasPerms('btn:access:editUser')"
      :disable="hasPerms('btn:access:editUser')"
    >
      編輯用戶(hù)
    </a-button>
  </div>
</template>
?
<script lang='ts'>
import { Vue, Component, Watch } from "vue-property-decorator";
import checkPermission from "@/utils/permission"; // 權(quán)限判斷函數(shù)
@Component
export default class Access extends Vue {
  hasPerms(params) {
    return checkPermission(params);
  }
}
</script>

到此這篇關(guān)于vue2模擬vue-element-admin手寫(xiě)角色權(quán)限的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)vue2 角色權(quán)限內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Vue狀態(tài)管理庫(kù)Vuex的入門(mén)使用教程

    Vue狀態(tài)管理庫(kù)Vuex的入門(mén)使用教程

    Vuex是一個(gè)專(zhuān)門(mén)為Vue.js應(yīng)用程序開(kāi)發(fā)的狀態(tài)管理庫(kù)。它采用了一個(gè)集中式的架構(gòu),將應(yīng)用程序的所有組件的狀態(tài)存儲(chǔ)在一個(gè)單獨(dú)的地方。這使得狀態(tài)的管理和維護(hù)變得更加容易
    2023-03-03
  • vue中如何使用embed標(biāo)簽PDF預(yù)覽

    vue中如何使用embed標(biāo)簽PDF預(yù)覽

    這篇文章主要介紹了vue中如何使用embed標(biāo)簽PDF預(yù)覽,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-05-05
  • vue使用Google地圖的實(shí)現(xiàn)示例代碼

    vue使用Google地圖的實(shí)現(xiàn)示例代碼

    這篇文章主要介紹了vue使用Google地圖的實(shí)現(xiàn)示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2018-12-12
  • vue登錄頁(yè)面設(shè)置驗(yàn)證碼input框的方法

    vue登錄頁(yè)面設(shè)置驗(yàn)證碼input框的方法

    這篇文章主要為大家詳細(xì)介紹了vue登錄頁(yè)面設(shè)置驗(yàn)證碼input框的方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-04-04
  • v-show和v-if的區(qū)別?及應(yīng)用場(chǎng)景

    v-show和v-if的區(qū)別?及應(yīng)用場(chǎng)景

    這篇文章主要介紹了v-show和v-if的區(qū)別及應(yīng)用場(chǎng)景,vue中v-show與?v-if的作用效果是相同的,都能控制元素在頁(yè)面是否顯示,但是也有一定的區(qū)別,下面文章梳理總結(jié)v-show和v-if的區(qū)別,需要的小伙伴可以參考一下
    2022-06-06
  • vue2中插槽(slot)的基本使用規(guī)范

    vue2中插槽(slot)的基本使用規(guī)范

    插槽(Slot)是Vue提出來(lái)的一個(gè)概念,正如名字一樣,插槽用于決定將所攜帶的內(nèi)容,插入到指定的某個(gè)位置,從而使模板分塊,具有模塊化的特質(zhì)和更大的重用性,下面這篇文章主要給大家介紹了關(guān)于vue2中插槽(slot)的基本使用規(guī)范的相關(guān)資料,需要的朋友可以參考下
    2022-03-03
  • Vue中如何使用mock模擬數(shù)據(jù)

    Vue中如何使用mock模擬數(shù)據(jù)

    這篇文章主要介紹了Vue中如何使用mock模擬數(shù)據(jù),具有很好的價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-06-06
  • vue實(shí)現(xiàn)界面滑動(dòng)效果

    vue實(shí)現(xiàn)界面滑動(dòng)效果

    這篇文章主要為大家詳細(xì)介紹了vue實(shí)現(xiàn)界面滑動(dòng)效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-07-07
  • VUE?mixin?使用示例詳解

    VUE?mixin?使用示例詳解

    混入mixin提供了一種非常靈活的方式,來(lái)分發(fā)Vue組件中的可復(fù)用功能,一個(gè)混入對(duì)象可以包含任意組件選項(xiàng),接下來(lái)通過(guò)本文給大家介紹VUE?mixin?使用,需要的朋友可以參考下
    2022-08-08
  • vue登錄路由權(quán)限管理的項(xiàng)目實(shí)踐

    vue登錄路由權(quán)限管理的項(xiàng)目實(shí)踐

    在開(kāi)發(fā)Web應(yīng)用程序時(shí),常常需要進(jìn)行登錄驗(yàn)證和權(quán)限管理,本文主要介紹了vue登錄路由權(quán)限管理的項(xiàng)目實(shí)踐,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-04-04

最新評(píng)論

富阳市| 和硕县| 宣威市| 宣恩县| 罗山县| 潞西市| 光泽县| 习水县| 景宁| 怀远县| 荥经县| 定结县| 阜新| 铁岭县| 莱阳市| 黄石市| 津市市| 南宁市| 稻城县| 中江县| 冕宁县| 连城县| 容城县| 宝兴县| 溧阳市| 沙雅县| 金沙县| 富阳市| 白河县| 南川市| 临澧县| 苏尼特右旗| 英超| 元朗区| 错那县| 农安县| 竹北市| 全椒县| 奇台县| 平阳县| 益阳市|