欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

vue如何根據(jù)權(quán)限生成動(dòng)態(tài)路由、導(dǎo)航欄

 更新時(shí)間:2022年03月30日 11:31:47   作者:秋刀魚笛滋味  
這篇文章主要介紹了vue如何根據(jù)權(quán)限生成動(dòng)態(tài)路由、導(dǎo)航欄,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

基本思路

1、創(chuàng)建vueRouter,用公共路由實(shí)例化

2、創(chuàng)建需要根據(jù)權(quán)限篩選的路由對象(在路由對象,添加必要的權(quán)限判斷字段)

3、登錄完成,由后端配合返回當(dāng)前用戶的權(quán)限集合

4、篩選出有權(quán)限的路由對象,利用vueRouter的addRoutes方法,生成完整路由

5、處理刷新頁面導(dǎo)致vueRouter重新實(shí)例化導(dǎo)致路由對象不完善 (利用router.beforeEach導(dǎo)航守衛(wèi),,利用addRoutes()完善 路由對象 )

6、側(cè)邊導(dǎo)航欄相關(guān)代碼

相關(guān)代碼

根據(jù)上面的順序

1、如下

Vue.use(Router)
// 公共路由
export const publicRoutes = [
  {
    path: '/',
    name: 'login',
    component: login,
    meta: {
      title: '登錄'
    }
  }
]
// 需要根據(jù)權(quán)限篩選的路由
export const asyncRoutes = [
  ...Home,
  ...Seting,
  ...CRM,
  {
    path: '*',
    component: login,
    meta: {
      hidden: true
    },
    redirect: '/'
  }
]
const vr = new Router({
  mode: 'history',
  routes: publicRoutes
})

2、以seting模塊為例,role為判斷是的權(quán)限字段,角色有這個(gè)字段對應(yīng)的值就有當(dāng)前頁面的權(quán)限

import Layout from '@/views/layout/layout.vue'
const account = r => require.ensure([], () => r(require('@/views/seting/account/account.vue')), 'seting');
const logs = r => require.ensure([], () => r(require('@/views/seting/logs/logs.vue')), 'seting');
const role = r => require.ensure([], () => r(require('@/views/seting/role/role.vue')), 'seting');
const Seting = [
  {
    path: '/seting',
    component: Layout,
    redirect: '/seting/account',
    meta: {
      title: '系統(tǒng)設(shè)置',
      role: '123c6c6514d416472e640bc3f49297c550',
      icon: 'icon-xitong'
    },
    children: [
      {
        path: 'account',
        name: 'account',
        component: account,
        meta: {
          title: '賬號管理',
          role: '1325cdeb897cc7f8e951d647de9b1d8e11',
        }
      },
      {
        path: 'logs',
        name: 'logs',
        component: logs,
        meta: {
          title: '日志管理',
          role: '14bfbb0337ad3e7e2c9fc101294c3fe645',
        }
      },
      {
        path: 'role',
        name: 'role',
        component: role,
        meta: {
          title: '角色管理',
          role: '1559d1c05d15a0dce5549b8bf5a58c0cf9',
        }
      }
    ]
  }
]
export default Seting

如果有一些詳情頁不需要在導(dǎo)航列表展示還可以添加字段,在生成導(dǎo)航欄時(shí)去掉

eg:

 {
            path: 'addJoiner',
            name: 'addJoiner',
            component: addJoiner,
            meta: {
              hidden: true,  // 隱藏字段
              title: '***詳情頁',
              role: '14bfbb0337ad3e7e2c9fc101294c3fe645',
            }
          },

3、登錄獲取權(quán)限集合和基本信息

 // 登錄
    login () {
      this.rememberPassword()
      this.$refs.form.validate((valid) => {
        if (valid) {
          this.loading = true
          let params = {
            login_name: this.form.user,
            password: this.form.password,
            code: this.form.yanzhenma,
          }
          this.$api.post('api/user/login', params).then(res => {
            if (res.err_code === 1) {
              // 把用戶的基本信息儲(chǔ)存在vuex,中
              this.$store.dispatch('setBaseInfo', res.data).then(() => {
                // 獲取有權(quán)限的路由表,添加到路由
                router.addRoutes(this.$store.getters.addRouters)
                this.$router.push({ name: 'home' })
              })
            }
            this.loading = false
          })
        }
      })

部分vuex代碼

如果不太理解,點(diǎn)擊下面鏈接:

vuex刷新就沒了解決方案

秒懂vuex

actions.js

// import api from '@/api'
const actions = {
  setBaseInfo ({
    commit
  }, data) {
    return new Promise(resolve => {
      commit('set_userInfo', data.userInfo)
      commit('set_token', data.token)
      commit('set_roles', data.menus)
      // 把基本信息保存在本地防止刷新之后丟失
      sessionStorage.setItem('baseInfo', JSON.stringify(data))
      resolve()
    })
  }
}
export default actions

mutations.js

const setStorage = (key, value) => {
  if (typeof (value) === 'object') {
    value = JSON.stringify(value)
  }
  sessionStorage.setItem(key, value)
}
/*
* 避免刷新之后vuex被重置,在sessionStorage做一個(gè)備份
 */
const mutations = {
  set_userInfo (state, payload) {
    state.userInfo = payload
    setStorage('userInfo', payload)
  },
  set_token (state, payload) {
    state.token = payload
    setStorage('token', payload)
  },
  set_roles (state, payload) {
    state.roles = payload
    setStorage('roles', payload)
  },
  set_breadcrumb (state, payload) {
    state.breadcrumb = payload
    setStorage('breadcrumb', payload)/*  */
  },
  changeCollapsed (state, payload) {
    state.isCollapsed = payload
  }
}
export default mutations

getters.js

import createdRoutes from '@/utils/createdRoutes.js'
import { asyncRoutes } from '@/router/index.js'
let getStoryage = (item) => {
  let str = sessionStorage.getItem(item)
  return JSON.parse(str)
}
const getters = {
  get_userInfo: (state) => {
    return state.userInfo ? state.userInfo : getStoryage('userInfo')
  },
  get_token: (state) => {
    return state.token ? state.token : sessionStorage.getItem('token')
  },
  get_roles: (state) => {
    return state.roles.length ? state.roles : getStoryage('roles')
  },
  addRouters: (state, getters) => {
    let routes = createdRoutes(asyncRoutes, getters.get_roles)
    return routes
  },
  get_breadcrumb: (state, getters) => {
    return state.breadcrumb.length ? state.breadcrumb : getStoryage('getStoryage')
  }
}
export default getters;

4、核心的篩選需要權(quán)限的路由方法:createdRoutes()

也就是3的getters,用到的方法,毫無保留奉上

/**
 * 判單當(dāng)前的路由對象是否在登錄人的權(quán)限之內(nèi)
 * @param {Array} roles 權(quán)限
 * @param {Object} route 路由
 */
function hasPermission (roles, route) {
  if (route.meta && route.meta.role) { // 路由需要權(quán)限就要在權(quán)限數(shù)組里面判斷
    return roles.includes(route.meta.role)
  } else { // 不需要權(quán)限就直接通過
    return true
  }
}
/**
 * 根據(jù)接口獲取的權(quán)限列表動(dòng)態(tài)生成當(dāng)前用戶的側(cè)邊導(dǎo)航欄,返回通過權(quán)限驗(yàn)證的路由數(shù)組
 * @param {Array} asyncRoutes 需要過濾的路由
 * @param {Array} roles 權(quán)限
 */
function createdRoutes (asyncRoutes, roles) {
  const accessedRouters = asyncRoutes.filter(route => {
    if (hasPermission(roles, route)) { // 當(dāng)前路由通過權(quán)限驗(yàn)證直接通過
      if (route.children && route.children.length) { // 當(dāng)前路由有子路由,就遞歸驗(yàn)證
        route.children = createdRoutes(route.children, roles)
      }
      return true
    }
    return false
  })
  return accessedRouters
}
export default createdRoutes

5、處理刷新帶來的問題

其實(shí)這里的代碼是連接1的,注意注釋

// 全局的導(dǎo)航守衛(wèi)
vr.beforeEach((to, from, next) => {
  // 刷新頁面之后導(dǎo)致vue-router和vuex重置,路由丟失,利用的就是刷新后vuex的state被重置判斷
  if (to.name !== 'login' && !store.state.token) {
    // 避免直接不登陸進(jìn)頁面
    if (!sessionStorage.getItem('token')) {
      location.href = '/'
      return
    }
    let data = JSON.parse(sessionStorage.getItem('baseInfo'))
    store.dispatch('setBaseInfo', data).then(() => {
      vr.addRoutes(store.getters.addRouters)
    })
  }
  // 設(shè)置面包屑導(dǎo)航
  let breadcrumb = to.matched.filter(item => item.meta.title)
  if (breadcrumb.length) {
    breadcrumb = breadcrumb.map(item => item.meta.title)
    store.commit('set_breadcrumb', breadcrumb)
  }
  // 設(shè)置title
  document.title = to.meta.title
  next()
})

6、側(cè)邊導(dǎo)航欄的完整代碼

還是遍歷的根據(jù)權(quán)限生成的路由表,干掉一些需要隱藏的詳情頁之類, 

這里的代碼和過濾l路由的核心函數(shù),要根據(jù)自己的業(yè)務(wù)做相應(yīng)的處理

element-ui的menu

<template>
  <el-menu class="el-menu-vertical-demo" :collapse="isCollapsed" background-color="#545c64" :default-active='activeIndex' text-color="#fff" active-text-color="#7EA8F5">
    <section v-for="(item,index) in addRouters" :key="item.name" :class="isCollapsed ? 'collapsed':''">
      <!-- 有子菜單 -->
      <el-submenu :index=" `${index+1}`" v-if="!item.meta.hidden && item.children && item.children.length">
        <template slot="title">
          <i :class="`icon iconfont ${item.meta.icon}`"></i>
          <span slot="title">{{item.meta.title}}</span>
        </template>
        <section v-for="(item2,index2) in item.children" :key="item2.name">
          <!-- 二級菜單有子菜單 -->
          <el-submenu :index="`${index+1}-${index2+1}`" v-if="item2.children && item2.children.length" class="sub2">
            <template slot="title">
              <span slot="title">{{item2.meta.title}}</span>
            </template>
            <!-- 三級菜單 -->
            <el-menu-item v-for="(item3,index3) in item2.children" v-if="!item3.meta.hidden" :index="item3.name" :key="index3" @click.native="$router.push({name:item3.name})">
              <span slot="title">{{item3.meta.title}}</span>
            </el-menu-item>
          </el-submenu>
          <!-- 二級菜單無子菜單 -->
          <!-- 不是隱藏的,詳情頁隱藏 -->
          <el-menu-item :index="item2.name" v-else-if="!item2.meta.hidden" @click.native="$router.push({name:item2.name})">
            <span slot="title">{{item2.meta.title}}</span>
          </el-menu-item>
        </section>
      </el-submenu>
      <!-- 無子菜單 -->
      <el-menu-item v-else-if="item.meta.hidden && item.children && item.children.length" :index="item.children[0].name" @click.native="$router.push({name:item.children[0].name})" class="item">
        <i :class="`iconfont ${item.children[0].meta.icon}`"></i>
        <span slot="title">{{item.children[0].meta.title}}</span>
      </el-menu-item>
    </section>
  </el-menu>
</template>
<script>
import { mapGetters } from 'vuex'
export default {
  props: {
    isCollapsed: {
      type: Boolean,
      default: false
    }
  },
  computed: {
    ...mapGetters(['addRouters']),
    activeIndex () { //集火的菜單
      return this.$route.name
    }
  }
}
</script>
<style lang="scss" scoped>
section {
  /deep/ .el-submenu__title {
    .icon {
      margin-right: 10px;
    }
    i {
      color: white;
      font-size: 14px;
    }
  }
  /deep/ .el-menu-item {
    padding-left: 50px !important;
  }
  /deep/ .el-menu-item.item {
    padding-left: 19px !important;
    i {
      color: white;
      font-size: 14px;
      margin-right: 12px;
    }
  }
  /deep/ .el-submenu .el-menu-item {
    min-width: 0;
  }
  /deep/ .el-submenu.sub2 .el-submenu__title {
    padding-left: 50px !important;
    i {
      margin-right: 0px;
    }
  }
  /*   /deep/ .el-submenu.sub2 .el-menu-item {
    text-indent: 12px;
  } */
}
.collapsed {
  width: 50px;
  /deep/ .el-submenu__title {
    .el-icon-arrow-right {
      display: none;
    }
    span[slot="title"] {
      display: none;
    }
  }
}
</style>

路由圖

在這里插入圖片描述

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。 

相關(guān)文章

  • vue獲取路由詳細(xì)內(nèi)容信息方法實(shí)例

    vue獲取路由詳細(xì)內(nèi)容信息方法實(shí)例

    獲取路由詳細(xì)內(nèi)容信息是我們?nèi)粘i_發(fā)中經(jīng)常會(huì)遇到的需求,下面這篇文章主要給大家介紹了關(guān)于vue獲取路由詳細(xì)內(nèi)容信息的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-12-12
  • Pycharm中開發(fā)vue?element項(xiàng)目時(shí)eslint的安裝和使用步驟

    Pycharm中開發(fā)vue?element項(xiàng)目時(shí)eslint的安裝和使用步驟

    這篇文章主要介紹了Pycharm中開發(fā)vue?element項(xiàng)目時(shí)eslint的安裝和使用,本文通過示例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-05-05
  • 使用命令行工具npm新創(chuàng)建一個(gè)vue項(xiàng)目的方法

    使用命令行工具npm新創(chuàng)建一個(gè)vue項(xiàng)目的方法

    Vue.js 提供一個(gè)官方命令行工具,可用于快速搭建大型單頁應(yīng)用。下面小編給大家分享使用命令行工具npm新創(chuàng)建一個(gè)vue項(xiàng)目的方法,需要的朋友參考下吧
    2017-12-12
  • Vue3 Ref獲取真實(shí)DOM學(xué)習(xí)實(shí)戰(zhàn)

    Vue3 Ref獲取真實(shí)DOM學(xué)習(xí)實(shí)戰(zhàn)

    這篇文章主要為大家介紹了Vue3 Ref獲取真實(shí)DOM學(xué)習(xí)實(shí)戰(zhàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-06-06
  • Element中el-table動(dòng)態(tài)合并單元格(span-method方法)

    Element中el-table動(dòng)態(tài)合并單元格(span-method方法)

    本文主要介紹了Element中el-table動(dòng)態(tài)合并單元格(span-method方法),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-05-05
  • 在vue中使用eslint,配合vscode的操作

    在vue中使用eslint,配合vscode的操作

    這篇文章主要介紹了在vue中使用eslint,配合vscode的操作,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-11-11
  • vue-cli3使用mock數(shù)據(jù)的方法分析

    vue-cli3使用mock數(shù)據(jù)的方法分析

    這篇文章主要介紹了vue-cli3使用mock數(shù)據(jù)的方法,結(jié)合實(shí)例形式分析了vue-cli3使用mock數(shù)據(jù)的相關(guān)實(shí)現(xiàn)方法與操作注意事項(xiàng),需要的朋友可以參考下
    2020-03-03
  • Vue組件封裝之input輸入框?qū)崙?zhàn)記錄

    Vue組件封裝之input輸入框?qū)崙?zhàn)記錄

    在vue中會(huì)將常用的組件進(jìn)行封裝,下面這篇文章主要給大家介紹了關(guān)于Vue組件封裝之input輸入框的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-10-10
  • vue實(shí)現(xiàn)2048小游戲功能思路詳解

    vue實(shí)現(xiàn)2048小游戲功能思路詳解

    這篇文章主要介紹了vue實(shí)現(xiàn)2048小游戲功能,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2018-05-05
  • vue時(shí)間選擇控件的使用方式

    vue時(shí)間選擇控件的使用方式

    這篇文章主要介紹了vue時(shí)間選擇控件的使用方式,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-10-10

最新評論