2

需求介绍

团队做的一个SPA项目,根据UI设计稿,菜单栏的信息需要从后端获取然后组装成路由,相当于异步路由。因为是单页面应用,所以要结合Vuex管理路由。

思路

该项目是基于vue-element-admin改造开发的,目录结构差不多。
vue-element-admin文档链接

文件目录结构

由于文章重点讲vuex的状态管理,不强调项目的扩展性,所以用最简单的目录。

├── 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的代码
      // 根据你的项目需求自由发挥
      // 举个栗子
      const asyncRoutes = [{
        path: '/addressBook',
        component: Layout,
        name: '通讯录',
        meta: { title: '通讯录', icon: 'document', affix: true, hasAddBtn: true, breadcrumb: false },
        children: []
      }]
      axios.get(url, params).then(value => {
        asyncRoutes[0].children = value
        // 你的代码........
        // ........
        // ........
        commit('SET_ROUTES', 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>

至此,功能完成。
如果这篇文章对你有帮助,欢迎点赞,收藏,谢谢~


DDD7
265 声望5 粉丝

幻想某一天顶替产品经理的前端妹砸(>V