VueとVue-Element-Admin(3):ルーティングとconstantRoutesとasyncRoutesの違い

Vue-Element-Adminのルーターは、常にconstantRoutesとasyncRoutesを使用してルートを定義します。store.modules.permission.jsには、2つの権限のデフォルトの判断方法があり、ナビゲーションガードはpermission.jsで実行されます。ルートディレクトリ内。ロジック;

constantRoutes:ログインページ、404、その他の一般的なページなど、動的な判断権限を必要としないルート。

asyncRoutes:権限を動的に決定し、addRoutesを介して動的に追加する必要があるページ

 1.vue-element-adminでの動的ルーティングの実装

routerフォルダーの下のindex.jsは、プロジェクトの合計ルーティングエントリです。index.jsがモジュールを登録した後、デフォルトでconstantRoutes非特権ルーティングを追加します。store/ modules /permission.jsで静的+動的ルーティング権限を維持します。ルートに保存するディレクトリの下のpermission.jsは、/ router /index.jsにあるナビゲーションガードロジックを実装します。

// router/index.js 部分代码

// 模块化,首先引入在modules目录下需要用的router
import componentsRouter from './modules/components'
import chartsRouter from './modules/charts'
import tableRouter from './modules/table'
import nestedRouter from './modules/nested'
import yzgTest from './modules/yzg'

//constantRoutes 是静态路由,不需要动态权限判断
export const constantRoutes = []
//constantRoutes 是动态路由,需要动态权限判断
export const asyncRoutes = []

// 
const createRouter = () => new Router({
  // mode: 'history', // require service support
  scrollBehavior: () => ({ y: 0 }),
  routes: constantRoutes
})

const router = createRouter()

// Detail see: https://github.com/vuejs/vue-router/issues/1234#issuecomment-357941465
export function resetRouter() {
  const newRouter = createRouter()
  router.matcher = newRouter.matcher // reset router
}

export default router

グローバル状態配列はstore / modules / permit.jsで維持されます。これは、現在ログインしているユーザーのメニュー権限を維持し、ガードをルーティングするときの動的ルーティングの切り替えと、store /での状態状態の動的ルーティングを完了します。 modules /permission.jsメンテナンスロジックは次のとおりです。

// 首先,从index.js中引入已经定义过的2个router数组
import { asyncRoutes, constantRoutes } from '@/router'

// 全局变量state,routes和addRoutes数组
const state = {
  routes: [],
  addRoutes: []
}

// mutations 是唯一可以更改state的函数,使用SET_ROUTES定义更改方法,SET_ROUTES(state, routes)的入参routes赋值给addRoutes数组,将constantRoutes静态路由数组增加routes;

const mutations = {
  SET_ROUTES: (state, routes) => {
    state.addRoutes = routes
    state.routes = constantRoutes.concat(routes)
  }
}

// vue中store状态管理,通过actions调用 mutations 中封装的方法来实现对于state更改,
// 这里是vue-element-admin中动态路由的主要判断逻辑发生地方,首先判定用户角色是否包含admin(可能多角色),是则将所有asyncRoutes 加入到constantRoutes,若用户角色没有包含admin,则调用filterAsyncRoutes函数,递归地判定asyncRoutes.roles属性是否有该角色,即是否有权限,将有权限的router赋值accessedRoutes 后加入到constantRoutes;

const actions = {
  generateRoutes({ commit }, roles) {
    return new Promise(resolve => {
      let accessedRoutes
      if (roles.includes('admin')) {
        accessedRoutes = asyncRoutes || []
      } else {
        accessedRoutes = filterAsyncRoutes(asyncRoutes, roles)
      }
      commit('SET_ROUTES', accessedRoutes)
      resolve(accessedRoutes)
    })
  }
}

//-----------------
// 两个上面使用的方法
function hasPermission(roles, route) {
  if (route.meta && route.meta.roles) {
    return roles.some(role => route.meta.roles.includes(role))
  } else {
    return true
  }
}

export function filterAsyncRoutes(routes, roles) {
  const res = []

  routes.forEach(route => {
    const tmp = { ...route }
    if (hasPermission(roles, tmp)) {
      if (tmp.children) {
        tmp.children = filterAsyncRoutes(tmp.children, roles)
      }
      res.push(tmp)
    }
  })

  return res
}

export default {
  namespaced: true,
  state,
  mutations,
  actions
}

 最後に、ルートディレクトリのpermission.jsにあるルーティングガードロジックを確認します。

// vue-element-admin中permission.js中导航守卫逻辑

import router from './router'
import store from './store'
import { Message } from 'element-ui'
import NProgress from 'nprogress' // progress bar
import 'nprogress/nprogress.css' // progress bar style
import { getToken } from '@/utils/auth' // get token from cookie
import getPageTitle from '@/utils/get-page-title'

// 进度条
NProgress.configure({ showSpinner: false }) // NProgress Configuration
// 白名单
const whiteList = ['/login', '/auth-redirect'] // no redirect whitelist

// 路由之前,逻辑判定
router.beforeEach(async(to, from, next) => {
  // 开始进度条
  NProgress.start()

  // set page title
  document.title = getPageTitle(to.meta.title)

  // determine whether the user has logged in
  const hasToken = getToken()

  // 有token,如果想去login则调到首页,如果是其他页面先判定是否有角色,有的话就跳过去,没有的话发请求得到永不信息,再调用函数维护store路由列表,报错要么没权限,要么是请求超时,就要返回error,清除token,返回登录页

// 没有token,且不是白名单内的,返回登录页
  if (hasToken) {
    if (to.path === '/login') {
      // if is logged in, redirect to the home page
      next({ path: '/' })
      NProgress.done() // hack: https://github.com/PanJiaChen/vue-element-admin/pull/2939
    } else {
      // determine whether the user has obtained his permission roles through getInfo
      const hasRoles = store.getters.roles && store.getters.roles.length > 0
      if (hasRoles) {
        next()
      } else {
        try {
          const { roles } = await store.dispatch('user/getInfo')
          const accessRoutes = await store.dispatch('permission/generateRoutes', roles)
          router.addRoutes(accessRoutes)
          next({ ...to, replace: true })
        } catch (error) {
          // remove token and go to login page to re-login
          await store.dispatch('user/resetToken')
          Message.error(error || 'Has Error')
          next(`/login?redirect=${to.path}`)
          NProgress.done()
        }
      }
    }
  } else {

    if (whiteList.indexOf(to.path) !== -1) {
      next()
    } else {
      // other pages that do not have permission to access are redirected to the login page.
      next(`/login?redirect=${to.path}`)
      NProgress.done()
    }
  }
})

// 进度条完毕
router.afterEach(() => {
  // finish progress bar
  NProgress.done()
})

 AsyncRoutesは意図的にmeta.rolesを使用してロールを定義するため、バックエンドリクエストがユーザーのロールを返した後、判定ロジックをpermission.jsにリンクできます。

2、vueでのルーティング

Vue-routerは、Vue.jsの公式ルーティングプラグインであり、vue.jsと緊密に統合されており、アクセスパスを設定し、パスとコンポーネントをマップするために使用されます。従来のページアプリケーションは、いくつかのハイパーリンクを使用してページを切り替えたりジャンプしたりします。vue-routerシングルページアプリケーションでは、パス間の切り替え、つまりコンポーネントの切り替えです。ルーティングモジュールの本質は、URLとページの間のマッピング関係を確立することですvue-routerは、単一ページのフロントエンドルーティングを実装する際にハッシュモードと履歴モードを提供します。

router.push(location)= window.history.pushState
別のURLに移動するには、router.pushメソッドを使用します。このメソッドは履歴スタックに新しいレコードを追加するため、ユーザーがブラウザの[戻る]ボタンをクリックすると、前のURLに戻ります。

おすすめ

転載: blog.csdn.net/yezonggang/article/details/109809019
おすすめ