Vuex異步獲取及管理動態Vue-router路由

需求介紹

團隊作的一個SPA項目,根據UI設計稿,菜單欄的信息須要從後端獲取而後組裝成路由,至關於異步路由。由於是單頁面應用,因此要結合Vuex管理路由。html

思路

該項目是基於vue-element-admin改造開發的,目錄結構差很少。
vue-element-admin文檔連接vue

文件目錄結構

因爲文章重點講vuex的狀態管理,不強調項目的擴展性,因此用最簡單的目錄。node

├── public                       
  ├──── index.html
├── node_modules
├── vue.config.js                     
├── dist                        
├── package.json                
├── src                         
  ├──── router.js                 constantRoutes存放的位置
  ├──── store                     vuex
    ├───── getter.js
    ├───── index.js
    ├───── modules
      ├────── menu.js
  ├──── views                     項目頁面
  ├──── layout.vue                全局導航欄
  ├──── App.vue                   
  ├──── main.js
  ├──── permission.js
  ├──── settings.js

代碼實現

src/router.js: 存放靜態路由

import Vue from 'vue'
import Router from 'vue-router'

Vue.use(Router)

export const constantRoutes = [
  {
    path: '/login',
    component: () => import('@/views/login/index'),
    hidden: true
  },
  {
    path: '/',
    component: () => import('@/layout')
    name: '基礎信息採集',
    meta: { title: '基礎信息採集', icon: 'document', breadcrumb: false },
    children: [
        …… some constant Routes
    ]
   }
]

const createRouter = () => new Router({
  scrollBehavior: () => ({ y: 0 }),
  routes: constantRoutes
})

const router = createRouter()

export default router

src/store/index.js

import Vue from 'vue'
import Vuex from 'vuex'
import menu from './modules/menu'
import getters from './getters'

Vue.use(Vuex)

const store = new Vuex.Store({
  modules: {
    menu
  },
  getters
})

export default store

src/store/modules/menu.js: 獲取動態路由信息的函數

import Layout from '@/layout'
import { constantRoutes } from '@/router'

const state = {
  routes: [],
  addRoutes: []
}

const mutations = {
  SET_ROUTES: (state, routes) => {
    state.addRoutes = routes
    // 這裏,state.routes由原先的靜態路由變爲了靜態路由+異步路由
    state.routes = constantRoutes.concat(routes)
  }
}

const actions = {
  generateRoutes({ commit, state }) {
    return new Promise((resolve, reject) => {
      const asyncRoutes = []
      // 動態獲取asyncRoutes的代碼
      resolve(asyncRoutes)
    }).catch(error => {
        reject(error)
    })
  }
}

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

src/store/getter.js

const getters = {
  all_routes: state => state.menu.routes
}
export default getters

src/layout.vue: 全局的layout組件,在這裏請求異步數據並渲染

<template>
    <sidebar-item v-for="route in all_routes" :key="route.path" :item="route" :base-path="route.path" />
</template>

<script>
import { mapGetters } from 'vuex'
import router from '@/router'
import store from '@/store'

export default {
  name: 'Layout'
  data() {
    return { }
  },
  computed: {
    ...mapGetters([
      'all_routes'
    ]),
  }
  created() {
    store.dispatch('menu/generateRoutes').then(res => {
      router.addRoutes(res)
    })
  }
}
</script>

至此,功能完成。
若是這篇文章對你有幫助,歡迎點贊,收藏,謝謝~git

相關文章
相關標籤/搜索