文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Vue router动态路由如何实现

2023-07-05 11:47

关注

本文小编为大家详细介绍“Vue router动态路由如何实现”,内容详细,步骤清晰,细节处理妥当,希望这篇“Vue router动态路由如何实现”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。

实现思路

思路其实很简单,也很明确:

将路由分为静态路由(staticRouters)、动态路由

静态路由初始化时正常加载

用户登陆后,获取相关动态路由数据,

然后利用vue:addRoute追加到vue实例中即可。 实现思路虽然很简单,但是过程并不是一帆风顺,需要注意的细节还是很多的

环境介绍

实现过程

路由文件处理(router/index.js):

import Vue from 'vue'import VueRouter from 'vue-router'import HomeLayout from '../layouts/HomeLayout'import store from '@/store/index'Vue.use(VueRouter)// 解决重复点击路由报错的BUGconst originalPush = VueRouter.prototype.pushVueRouter.prototype.push = function push(location) {    return originalPush.call(this, location).catch((err) => err)}const routes = [{path: '/',name: 'homeBase',component: HomeLayout,redirect: {name: 'home'},children: [// 门户路由{path: 'home',name: 'home',component: () => import('../views/portal/Home.vue'),},{path: 'lists',name: 'lists',component: () => import('../views/portal/Lists.vue'),},{path: 'detail',name: 'detail',component: () => import('../views/portal/Detail.vue'),},]},]// 定义静态路由集合const staticRouterMap = ['home','lists','detail']const router = new VueRouter({mode: 'history',base: process.env.BASE_URL,routes,})// 路由全局拦截// 以下可根据业务逻辑自行在拦截路由中进行处理,此处仅以本人业务作为示例展示// 本示例以 vuex+sessionStorage相互配合完成动态路由的数据存储// 仅以vuex存储获取到的动态路由信息后,在刷新页面时,动态路由信息是会丢失,// 从而导致页面404router.beforeEach((to, from, next) => {const userState = JSON.parse(sessionStorage.getItem('userState'))if (!userState || !userState.isLogin) {// 没有登录// 如果前往页面非公共路由,则跳转至首页if (staticRouterMap.indexOf(to.name) < 0) {next({name: 'home'})} else {next()}} else {// 登录// 已经存在路由列表: 注意刚登陆成功第一次调转route时相应store数据还未更新const hasGetRoute = store.getters['user/hasGetRoute']const routeMap = JSON.parse(sessionStorage.getItem('routeMap'))if(!hasGetRoute && routeMap) {            // 刷新页面且有route记录数据,可再次追加动态路由store.dispatch('user/updateRouteOfUser', routeMap)next({...to, replace: true})} else {next()}}})export default router

view数据处理

<template><div class="home"><div>这是demo</div><div><div v-show="!isLogin"><a-divider>调用接口: 模拟登陆</a-divider><div ><a-space :size="size"><a-button type="primary" @click="login()">用户登陆</a-button></a-space><p>{{loading}}</p></div></div></div></div></template><script>// @ is an alias to /srcimport {Base64} from 'js-base64'import User from '../../api/user'import {mapGetters,mapMutations,mapActions} from 'vuex'export default {name: 'home',data() {return {size: "middle",user: {'name': 'xxxx','pass': Base64.encode('xxxx')},}},components: {},computed: {...mapGetters('user', ['isLogin', 'userInfo', 'hasGetRoute'])},methods: {...mapMutations('user', ['setUserState']),...mapActions('user', ['getUserInfo', 'getDynamicRouteOfUser']),login() {if (this.isLogin) {this.$router.push({path: '/user'})} else {// 模拟用户User.login(this.user).then(res => {this.setUserState({'isLogin': true,'ut': res.data.user_token,'userType': 1})this.getUserInfo()//以下就是根据用户登陆信息,获取动态路由信息操作this.getDynamicRouteOfUser(type).then(() => {this.$router.push({path: '/user'})})}).catch(() => {})}},},}</script><style lang="scss" scoped>.home {padding: 20px;}</style>

vuex

import VueRouter from '../../router'import UserApi from '../../api/user'import axios from 'axios'import TeacherLayout from '@/layouts/Layout'import NotFound from '@/layouts/404'const user = {    namespaced: true,    state: {        // 用户状态相关         userState: JSON.parse(sessionStorage.getItem('userState')) || {ut: '', isLogin: false, userType: null},        // 用户信息相关        userInfo: JSON.parse(sessionStorage.getItem('userInfo')) || {},        // 是否获取route        hasGetRoute: false,        // routeMap        routeMap: JSON.parse(sessionStorage.getItem('routeMap')) || [],    },    getters: {        ut : state => state.userState.ut,        isLogin: state => !!state.userState.isLogin,        userInfo: state => state.userInfo,        hasGetRoute: state => state.hasGetRoute,        routeMap: state => state.routeMap[0].children,    },    mutations: {        setUserState(state, playload) {            state.userState = playload            sessionStorage.setItem('userState', JSON.stringify(state.userState))        },        setUserInfo(state, playload) {            state.userInfo = playload            sessionStorage.setItem('userInfo', JSON.stringify(state.userInfo))        },        setRouteMap(state, routers) {            state.routeMap = routers            // 为了防止用户刷新页面导致动态创建的路由失效,将其存储在本地中            sessionStorage.setItem('routeMap', JSON.stringify(routers));        },        setDynamicRouteMap(state, routers) {            state.hasGetRoute = true            let routerMaps = filterRouter(routers)            // 最后追加404路由            routerMaps.push({                path: '*',                component: NotFound            })            // 追加路由            // 这块是重点,如果直接使用addRoute是无效的            routerMaps.forEach(item => {                VueRouter.addRoute(item);            })        },        resetLogin() {            sessionStorage.clear()        }    },    actions: {        // 获取用户信息        async getUserInfo({commit}) {            await UserApi.user().then(res => {                commit('setUserInfo', res)            }).catch(error => {                console.log(error)            })        },        // 获取用户授权动态路由        async getDynamicRouteOfUser({commit}, type) {            let flag = false            // mock api            mockRouter().then(res => {                commit('setRouteMap', res.data)                commit('setDynamicRouteMap', res.data)                flag = true            }).catch(err => {                console.log(err)            })            return flag        },        // 刷新重置路由        updateRouteOfUser({commit}, routerMap) {            commit('setDynamicRouteMap', routerMap)        },    }}// handle viewsconst loadView = (viewPath) => {    return () => import('@/views/' + viewPath)}// Handle routersconst filterRouter = (routers) => {    return routers.filter((router) => {   // 区分布局与视图文件,因为加载方式不同        if (router.component === 'Layout') {            router.component = Layout        }else {            // view            router.component = loadView(router.component)        }        // 删除路由记录中的无用字段:这段是本示例与后台协商的,但在vue-router中不被支持的字段信息,可忽略        if (!router.redirect || !router.redirect.length) { delete router.redirect }        // 判断是否存在子路由,并递归调用自己        if(router.children && router.children.length) {            router.children = filterRouter(router.children)        }        return true    })} // mock 数据async function mockRouter() {    const url = 'http://localhost:8080/t.json'    let routerData    await axios.get(url).then(res => {        routerData = res.data    }).catch(err => {        console.log(err)    })    return routerData}export default user;

路由数据(demo)

{    "data":[        {            "title":"demo",            "name":"x",            "pname":"",            "path": "/x",            "type": 1,            "component": "Layout",            "redirect": {"name": "xx"},            "children": [                {                    "title":"child1",                    "name":"xx",                    "pname":"x",                    "path": "",                    "type": 2,                    "icon": "desktop",                    "component": "xx.vue",                    "redirect": {}                },                {                    "title":"child1",                    "name":"xx",                    "pname":"tBase",                    "path": "xx",                    "type": 2,                    "icon": "container",                    "component": "xx.vue",                    "redirect": {"name": "xxx"},                    "children": [                        {                            "title":"child2",                            "name":"xx",                            "pname":"xx",                            "path": "xx",                            "type": 2,                            "icon": "unordered-list",                            "component": "xx.vue",                            "redirect": {}                         }                    ]                },            ]        }    ]}

读到这里,这篇“Vue router动态路由如何实现”文章已经介绍完毕,想要掌握这篇文章的知识点还需要大家自己动手实践使用过才能领会,如果想了解更多相关内容的文章,欢迎关注编程网行业资讯频道。

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯