手把手教你vue实现动态路由

目录
  • 1、什么是动态路由?
  • 2、动态路由的好处
  • 3、动态路由如何实现
  • 总结

1、什么是动态路由?

动态路由,动态即不是写死的,是可变的。我们可以根据自己不同的需求加载不同的路由,做到不同的实现及页面的渲染。动态的路由存储可分为两种,一种是将路由存储到前端。另一种则是将路由存储到数据库。动态路由的使用一般结合角色权限控制一起使用。

总结:

1)路由可变,不是写死的,动态加载

2)存储分两种:存前端,存数据库

2、动态路由的好处

使用动态路由可以跟灵活,无需手工维护,我们可以使用一个页面对路由进行维护。如果将路由存储到数据库,还可以增加安全性。

总结:

1)灵活,无需手工维护

2)增加安全性

3、动态路由如何实现

在此以路由存储在数据库为例

流程:一般我们在登录的时候,根据登录用户的角色返回此角色可以访问的页面的路由,前端将路由存储到vuex(vuex存储的数据必须可持久的,不要一刷新页面就不见),我们在路由前置守卫处动态添加拿到的路由,对页面进行渲染。

1)此为我的router目录,index.js对路由添加,守卫拦截等处理。static-route.js为前端定义的静态路由,不需要动态加载的,如登陆页面,忘记密码页面,404页面等。

index.js

import Vue from 'vue'
import $cookies from 'vue-cookies'
import VueRouter from 'vue-router'
import store from '../store'​
import staticRoute from './static-route.js'​​​
Vue.use(VueRouter)​​
const router = new VueRouter({
	mode: 'history',
	base: process.env.BASE_URL,
	routes: staticRoute //staticRoute为静态路由,不需动态添加
})​
let isToken = true
router.beforeEach(async (to, from, next) => {
	//定义isToken为true和vuex不为空时添加路由
	if (isToken && store.state.routers.routers.length != 0) {
		//从vuex中获取动态路由
		const accessRouteses = await store.state.routers.routers;
		//动态路由循环解析和添加
		accessRouteses.forEach(v => {
			v.children = routerChildren(v.children);
			v.component = routerCom(v.component);
			router.addRoute(v); //添加
		})
		isToken = false //将isToken赋为 false ,否则会一直循环,崩溃
		next({
			...to, // next({ ...to })的目的,是保证路由添加完了再进入页面 (可以理解为重进一次)
			replace: true, // 重进一次, 不保留重复历史
		})​
	} else {
		if (to.name == null) {
			next("/404")
		} else {
			if (to.meta.title) { //判断是否有标题
				document.title = to.meta.title //给相应页面添加标题
			}
			next()
		}​
	}​
})​
function routerCom(path) { //对路由的component解析
	return (resolve) => require([`@/views/${path}`], resolve);
}​
function routerChildren(children) { //对子路由的component解析
	children.forEach(v => {
		v.component = routerCom(v.component);
		if (v.children != undefined) {
			v.children = routerChildren(v.children)
		}
	})
	return children
}​​
export default router​

2)登陆成功后将获取到的动态路由存储到vuex

vuex—>index.js

import Vue from 'vue'
import Vuex from 'vuex'
//数据持久化
import createPersistedState from "vuex-persistedstate";
​
Vue.use(Vuex)
const routers = {
  namespaced: true,
  state: () => ({
    routers:"",
  }),
  mutations: {
    routers(state, newsdata) {
      state.routers = newsdata
    },
​
  },
  actions: {
    routers(context) {
      context.commit('routers')
    },
  },
  getters: {
    routers(state) {
      console.log("getters", state)
      return state.routers
    },

  }
}
​
​
const store = new Vuex.Store({
  modules: {
    routers: routers,
  },

  // 数据持久化
  plugins: [createPersistedState({
    //key是存储数据的键名
    key: 'routersData',
    //paths是存储state中的那些数据,如果是模块下具体的数据需要加上模块名称,如user.token
    paths: ["routers.routers"]
  })]
})
​
​
export default store

我的动态路由模板

//动态路由
const dynamicRoute = [{
  "path": "/main",
  "name": "main",
  "redirect": "/main/index",
  "component": "main/main.vue",
  "children": [{
      "path": "index",
      "name": "index",
      "component": "index/index.vue",
      "meta": {
        "name": "index",
        "title": "首页",
        "icon": "el-icon-location",
        "menu":true //true为菜单栏
      }
    },
    {
      "path": "Configuration",
      "name": "Configuration",
      "redirect": "Configuration/route",
      "component": "Configuration/index.vue",
      "roles": ['developer', "admin"], //  developer、admin角色的用户才能访问该页面
      "meta": {
        "title": "配置",
        "icon": "el-icon-location",
        "menu":true
      },
      "children": [{
          "path": "route",
          "name": "route",
          "component": "Configuration/route/index.vue",
          "meta": {
            "title": "菜单",
            "icon": "",
            "menu":true
          },
        }, {
          "path": "user",
          "name": "user",
          "component": "Configuration/user/index.vue",
          "meta": {
            "title": "用户管理",
            "icon": "el-icon-location",
            "menu":true
          },
        },
        {
          "path": "admin",
          "name": "admin",
          "component": "Configuration/admin/index.vue",
          "meta": {
            "title": "管理员管理",
            "icon": "",
            "menu":true
          },
        },

        {
          "path": "userEdit",
          "name": "userEdit",
          "component": "Configuration/user/user-Edit.vue",
          "meta": {
            "title": "编辑用户",
            "icon": "",
            "menu":false
          },
        },
      ]
    },
    {
      "path": "check",
      "name": "check",
      "redirect": "check/user",
      "component": "check/index.vue",
      "roles": ['developer', "admin", "check"], //  developer、admin角色的用户才能访问该页面
      "meta": {
        "title": "审核",
        "icon": "el-icon-location",
        "menu":true
      },
      "children": [{
          "path": "user",
          "name": "checkUser",
          "component": "check/check-user/index.vue",
          "meta": {
            "title": "用户实名审核",
            "icon": "el-icon-location",
            "menu":true
          }
        },
        {
          "path": "enterprise",
          "name": "checkEnterprise",
          "component": "check/check-enterprise/index.vue",
          "meta": {
            "title": "企业认证审核",
            "icon": "el-icon-location",
            "menu":true
          },
        },
        {
          "path": "checkNormImage",
          "name": "checkNormImage",
          "component": "check/check-norm-image/index.vue",
          "meta": {
            "title": "标准照认证审核",
            "icon": "el-icon-location",
            "menu":true
          },
        },
        {
          "path": "checkHiringJobs",
          "name": "checkHiringJobs",
          "component": "check/check-hiring-Jobs/index.vue",
          "meta": {
            "title": "求职、招聘认证审核",
            "icon": "el-icon-location",
            "menu":true
          },
        }
      ]
​
    }
  ]
}, ]
export default dynamicRoute

路由管理界面(可能有不完善的地方)

讲一讲遇到的坑及注意点

1)“component”: “check/check-norm-image/index.vue”, 用字符串再在解析,不要像静态路由一样。否则第一次进去可以,刷新就变空白

2)此处为重要的一点,直接用next()不行

next({
      ...to, // next({ ...to })的目的,是保证路由添加完了再进入页面 (可以理解为重进一次)
      replace: true, // 重进一次, 不保留重复历史
    })

3)由于添加完路由还会重复执行一遍路由守卫,所有必须确保不要一直死循环添加路由。否则直接崩溃。这里我用的是isToken变量确保不循环。

总结

到此这篇关于vue实现动态路由的文章就介绍到这了,更多相关vue实现动态路由内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • vue 实现动态路由的方法

    很多时候我们在项目的路由都是在前端配置好的 但是有的时候为了进行全面的权限控制,会需要后台给出路由表,前端再渲染.不用在前端配置. 下面主要讲一下思路 1.和后台小哥哥沟通好数据,把我们前端配置的路由表数据给他,他就能看懂了 2.拿到数据需要我们自己再处理 路由中的component后台是给不了的,这里我们只需要后台小哥哥按照我们提供的前端component路径给数据,我们循环加载就可以了 //view就是后台给的数据 return () => import(`@/view/modules/${

  • vue系列之动态路由详解【原创】

    开题 最近用vue来构建了一个小项目,由于项目是以iframe的形式嵌套在别的项目中的,所以对于登录的验证就比较的麻烦,索性后端大佬们基于现在的问题提出了解决的方案,在看到他们的解决方案之前,我先画了一个比较标准的单系统的解决方案. 本文目录: 一: 设想 二: 讨论 三:实现 四:总结 一: 设想 简单解释下上图就是: 首先前端从cookie获取token,如果没有token就跳转到登录页面登录,登录验证之后生成token存在数据库中并返回给前端:前端将这个token保存下来,为了让在浏览器新

  • 详解vue路由篇(动态路由、路由嵌套)

    什么是路由?网络原理中,路由指的是根据上一接口的数据包中的IP地址,查询路由表转发到另一个接口,它决定的是一个端到端的网络路径. web中,路由的概念也是类似,根据URL来将请求分配到指定的一个'端'.(即根据网址找到能处理这个URL的程序或模块) 使用vue.js构建项目,vue.js本身就可以通过组合组件来组成应用程序:当引入vue-router后,我们需要处理的是将组件(components)映射到路由(routes),然后在需要的地方进行使用渲染. 一.基础路由 1.创建vue项目,执行

  • vue动态路由实现多级嵌套面包屑的思路与方法

    前言 最近在工作中遇到了一个问题,是关于vue动态路由多级嵌套面包屑怎么弄(不是动态路由嵌套可以尝试用 this.$route.matched方法获取到path和name集合,动态的嵌套获取不到全部具体的id) 功能比如:A列表页面路由如/a,点击任意一列进入任意一个A的详情页面名字为B,/b/03(这个是动态路由弄是吧,03就是id嘛),点击B页面任意一列,再进入B的详情页名字为C,路由如/bdetail/01;现在弄面包屑要获取到的路由是刚刚打开的,如(/a:/b/03:/bdetail/0

  • Vue动态路由缓存不相互影响的解决办法

    关于react与vue中的key 之前在学习react的时候,常常遇到循环渲染组件时会提示需要在循环组件中加上key属性,比如有一组列表: import React, { Component } from 'react'; export default calss MainApp extends Component { state = { student: [ { name: 'Jenny', id: 'a001' }, { name: 'Jerry', id: 'a002' }, ] } re

  • vue实现动态路由详细

    目录 一.前端控制 1.在router.js文件(把静态路由和动态路由分别写在router.js) 2.store/permission.js(在vuex维护一个state,通过配角色来控制菜单显不显示) 3.src/permission.js 4.侧边栏的可以从vuex里面取数据来进行渲染 二.后端控制路由 1.store/permission.js,在vuex里面发送请求获取数据 2.整理一份数据结构,存到表里 3.写一个转化方法,把获取到的数据转换成router结构 主流的实现方式: 简单

  • 手把手教你vue实现动态路由

    目录 1.什么是动态路由? 2.动态路由的好处 3.动态路由如何实现 总结 1.什么是动态路由? 动态路由,动态即不是写死的,是可变的.我们可以根据自己不同的需求加载不同的路由,做到不同的实现及页面的渲染.动态的路由存储可分为两种,一种是将路由存储到前端.另一种则是将路由存储到数据库.动态路由的使用一般结合角色权限控制一起使用. 总结: 1)路由可变,不是写死的,动态加载 2)存储分两种:存前端,存数据库 2.动态路由的好处 使用动态路由可以跟灵活,无需手工维护,我们可以使用一个页面对路由进行维

  • vue router动态路由下让每个子路由都是独立组件的解决方案

    vue-router 之动态路由 vue-router官网上面是这样说的 // 带查询参数,变成 /register?plan=private router.push({ path: 'register', query: { plan: 'private' }}) 然后,我就这样写了: this.$router.push({path:'manage', query: {id: 'tasklist'}})1 结果很明显,失败了.然后我就默默的再次看了一下官网,结果发现了这句话 // 命名的路由 r

  • vue router动态路由设置参数可选问题

    在日常工作中,我们需要将匹配到的所有路由,映射到一个组件上. 如下代码想要达到的效果: 不传page和id,则映射到user默认list页面 传page和id,根据page不同,显示不同的页面 问题 使用以下代码片段是不能实现以上效果的,因为默认情况下page和id参数是必传的,如果不传参数,则会根据默认路由跳转到home页面 new Router({ routes: [ { path: '/user/:page/:id', name: 'User', component: () => impo

  • Vue实现动态路由导航的示例

    目录 1.导航守卫 二.功能展示 三.原理 四.功能实现 小结 1.导航守卫 “导航” 表示路由正在发生改变 正如其名,vue-router 提供的导航守卫主要用来通过跳转或取消的方式守卫导航.有多种机会植入路由导航过程中:全局的, 单个路由独享的, 或者组件级的. 记住参数或查询的改变并不会触发进入/离开的导航守卫.你可以通过观察 $route 对象来应对这些变化,或使用 beforeRouteUpdate 的组件内守卫. v-router官网:https://router.vuejs.org

  • vue router 动态路由清除方式

    目录 router 动态路由清除 vue-router退出登录清空路由 router 动态路由清除 重置matcher可达到路由还原效果 在用户退出时调用 resetRouter(router) 即可还原路由 import Vue from 'vue' import Router from 'vue-router' import { constantRouterMap } from '...' //导入初始化router   // 传入当前router export function reset

  • 五步教你用Nginx部署Vue项目及解决动态路由刷新404问题

    目录 步骤一:改端口 步骤二: 打包 步骤三:将dist文件夹上传到服务器上 步骤四:修改nginx.conf(重中之重) 步骤五:重启nginx 总结 期末月前本来部署过一次,昨天部署的时候发现又给忘了,而且出了很多问题,在这统一汇总一下. 步骤一:改端口 在vue.config.js下的devServer把host改成服务器的地址 步骤二: 打包 用npm run build打包,最后是这样的,并且目录下多了个dist文件夹 步骤三:将dist文件夹上传到服务器上 我用的xshell,没办法

  • Vue Router 实现动态路由和常见问题及解决方法

    个人理解:动态路由不同于常见的静态路由,可以根据不同的「因素」而改变站点路由列表.常见的动态路由大都是用来实现:多用户权限系统不同用户展示不同导航菜单. 如何利用Vue Router 实现动态路由 Vue项目实现动态路由的方式大体可分为两种: 前端将全部路由规定好,登录时根据用户角色权限来动态展示路由: 路由存储在数据库中,前端通过接口获取当前用户对应路由列表并进行渲染: 第一种方式在很多Vue UI Admin上都实现了,可以去读一下他们的源码理解具体的实现思路,这里就不过多展开.第二种方式现

  • Vue三层嵌套路由的示例代码

    Vue嵌套路由: 实现效果(路由三层嵌套,点击一级tab显示二级tab效果,二级tab点击切换对应内容,不在tab区域里的内容,切换时不重复渲染): Demo访问时路径:http://IP:端口/#/routers/ 1.建立案例文件夹 page/routers/ 1 routers/index.vue <template> <div> <router-link :to="{name: 'rindex_rhome'}" class="rlink&

随机推荐