vue-router 添加動態路由

這篇文章是基於 vue-router v4.02 版本來實現的。vue-router v4.0.2 的版本與 v.3.x 的版本區別有很多,可以直查看一下這裏, 本片文章只說一下怎麼使用vue-router去動態創建路由。具體可以直接看代碼,一目瞭然了。

使用vue-cli3創建項目

vue create router-test


設置路由 "router/index.js"

import { createRouter, createWebHashHistory } from 'vue-router'
import defaultRouter from './defaultRouter'
import store from '@/store'
import dynamicRouter from './dynamicRouter'

const router = createRouter({
  history: createWebHashHistory(),
  routes: defaultRouter,
  scrollBehavior(to, from, savedPosition) {
    // keep-alive 返回緩存頁面後記錄瀏覽位置
    if (savedPosition && to.meta.keepAlive) {
      return savedPosition;
    }
    // 異步滾動操作
    return new Promise((resolve) => {
      setTimeout(() => {
        resolve({ x: 0, y: 0 })
      }, 200)
    })
  }
})



// 重新添加路由並消除路由重複警告
const selfaddRoutes = function(params) {
  params.forEach(item => router.addRoute(item))
}

router.beforeResolve(async (to, from, next) => {
  let { hasRoute } = store.state; //防止路由重複添加

  if (hasRoute) {
    next();
  } else {
    await dynamicRouter(selfaddRoutes)

    let routes = router.getRoutes(); //重新設置跳轉路由
    routes.forEach((item) => {
      if (to.path == item.path) {
        to.name = item.name;
      }
    })

    next({ ...to, replace: true })

  }
})

export default router


  1. v4版本去掉了 addRoutes() 方法,現用 addRoute(),所有路由只能一個一個添加;
  2. 默認路由處添加了 /:pathMatch(.*)* 全路由匹配,在首次(刷新)導航進入到一個動態路由地址,這時會直接跳到 page_error 頁面, 所以在導航進入動態路由地址時需要重新將 to 與最新的路由列表進行匹配,這裏直接更改 to.name 值,即可;

使用vuex設置路由狀態 "store/index.js"

import { createStore } from 'vuex'

export default createStore({
  state: {
    "hasRoute": false
  },
  metters:{
  	"hasRoute" : state => state.hasRoute
  },
  mutations: {
  	 setHasRoute(state, hasRoute){
  	 	state.hasRoute = hasRoute;
  	 }
  },
  actions: {},
  modules: {}
})


設置默認路由 "router/defaultRouter.js"

import Home from '@/views/Home.vue'
const defaultRouter = [{
    path: '',
    name: 'Home',
    component: Home
  },
  {
    path: '/about',
    name: 'About',
    component: () => import('@/views/About.vue')
  }, {
    path: '/:pathMatch(.*)*',
    name: "page_error",
    component: () => import('@/views/error_page/404'),
    meta: {
      requiresAuth: false
    }
  }
]

export default defaultRouter


設置動態路由 "router/dynamicRouter.js"

import store from '@/store'
import defaultRouter from './defaultRouter'

import axios from 'axios';

//重新構建路由對象
let menuMap = function(menu) {
  return menu.map(v => {
    let { path, name, component, title, icon = "" } = v;
    let item = {
      path,
      name,
      meta: {
        title,
        icon
      },
      component: () => import(`@/${component}`)
    };
    if (v.children) {
      item.children = menuMap(v.children);
    }
    return item;
  })
}

//異步獲取路由列表
const addPostRouter = function(selfaddroutes) {
  return new Promise((resolve, reject) => {
    axios({
      url: './static/menu.json'
    }).then((res) => {
      defaultRouter.unshift(...menuMap(res.data));
      selfaddroutes(defaultRouter);
      store.commit('setHasRoute', true); //更新路由狀態;
      resolve(true)
    }).catch((err) => {
      reject(err);
    })
  })
}

export default addPostRouter;


menu.json

該文件路徑地址爲 "public/static/menu.json"

[{
    "path": "/add",
    "name": "add",
    "title": "添加用戶",
    "component": "views/user/add"
},
{
    "path": "/list",
    "name": "list",
    "title": "用戶列表",
    "component": "views/user/list"
},
{
    "path": "/task",
    "name": "task",
    "title": "任務",
    "component": "views/task/index",
    "children": [
    {
        "path": "list",
        "name": "task_list",
        "title": "任務列表",
        "component": "views/task/list"
    },
    {
        "path": "add",
        "name": "task_add",
        "title": "添加任務",
        "component": "views/task/add"
    }]
}]


刪除路由

router.addRoute({ path: '/about', name: 'about', component: About })
// remove the route
router.removeRoute('about')

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章