vue动态设置路由,vue3.0动态路由

  vue动态设置路由,vue3.0动态路由

  本文主要介绍了vue一步实现动态路由的方法,具有很好的参考价值。希望对你有帮助。如有错误或不足之处,请不吝赐教。

  

目录

  动态路由的静态路由配置回顾说一些作者遇到的问题。后记是最近为vue项目写的。需要从后台发送当前用户对应权限的路由表,前端通过接口得到后处理(后端处理路由),即配置vue动态路由。

  我在这个问题上花了很多时间是因为误信了一些网上的文章: (,导致了很多时间。想想,还是自己写篇文章记录下我遇到的坑吧。

  接下来,手把手记录如何从头开始配置vue动态路由。

  首先,我们来看看静态路由的配置。下面简单预习一下。如果熟悉,可以直接跳过。这一部分是为了熟悉路由的配置。配置动态路由实际上就是将静态路由存储到数据库中,然后取出放入路由表中(静态路由直接写在路由表中)。

  

静态路由的回顾

  1.创建router/index.js文件。这里只有一些简单的页面。

  从“vue”导入Vue

  从“vue路由器”导入路由器

  从“@/查看/登录/登录”导入登录

  从“@/布局/索引”导入索引

  从 @/layout/welcome/Welcome 导入欢迎

  Vue.use(路由器)

  导出默认新路由器({

  路线:[

  {

  路径:“/login”,

  名称:登录,

  组件:登录

  },

  {

  路径:“/”,

  组件:索引,

  重定向:“/欢迎”,

  meta: {requireAuth: true},

  儿童:[

  {

  路径:“/welcome”,

  成分:欢迎光临,

  名称:主页,

  Meta: {title:主页,requireAuth: true}

  }

  ]

  }

  ]

  })

  2.创建router/permission.js文件并配置导航保护。每次路由跳转前可以做一些操作。后面获取动态路由的操作也在这里配置。

  从“@/router/index”导入路由器

  导入 element-ui/lib/theme-chalk/index . CSS

  导入 @ fortawesome/font awesome-free/CSS/all . min . CSS

  从“NProgress”导入nprogress

  导入 nprogress/nprogress.css

  NProgress.configure({

  缓解:“缓解”,//动画模式

  速度:500,//增加进度条的速度

  ShowSpinner: false,//是否显示加载ico

  TrickleSpeed: 200,//自动递增间隔

  最小值:0.3 //初始化时的最小百分比

  })

  //白名单

  const whiteList=[/login] //无重定向白名单

  //导航保护装置

  router.beforeEach((收件人,发件人,下一个)={

  NProgress.start()

  if (to.meta.requireAuth) {

  //确定路由是否需要登录权限。

  if(session storage . getitem( log in name )!==null) {

  //确定本地是否存在令牌。

  下一个()

  //这是后面要获得异步路由的地方。

  }否则{

  //如果没有登录,跳转到登录页面。

  下一个({

  路径:“/login”

  })

  }

  }否则{

  if (whiteList.indexOf(to.path)!==-1) {

  下一个()

  }否则{

  if(session storage . getitem( log in name )!==null) {

  //确定本地是否存在令牌。

  下一个(`/?redirect=${to.path} `)

  }否则{

  下一个(`/登录?redirect=${to.path} `)

  }

  }

  }

  })

  router.afterEach(()={

  //在进入新页面组件之前关闭进度条。

  NProgress.done()

  })

  这里引用一个插件,Nprogress,就是下面这个蓝色的小进度条。不,没关系。

  3.将刚刚创建的路由器下的index.js文件和permission.js文件引入main.js,如下

  从 @/router 导入路由器

  “导入”。/路由器/权限

  新Vue({

  埃尔: #app ,

  路由器,

  店,

  组件:{ App },

  模板:“应用程序/”

  })

  4.把路线跳转的查看区放到App入口,所有跳转的路线页面都显示在这里。

  //APP.vue文件

  div id=应用程序

  路由器-视图/

  /div

  现在静态路由准备好了,可以正常跳转了!

  文件夹看起来像这样。

  

动态路由的配置

  接下来,配置动态路由!

  我来解释哪里有坑。

  1.首先router/index.js,没什么好改的。只需删除需要动态获取的路由信息,可以留下一些静态路由,比如登陆页、首页等。如果您删除所有路线,您可以将路线指定为[]。

  2.创建一个文件,我将其命名为getAsyncRouter.js,以处理获取的动态路由信息。

  //用于处理动态菜单数据,并将其转换为路由形式。

  导出函数fnadddynamicmenroutes(menuList=[],routes=[]) {

  //用于保存常用路由数据

  let temp=[]

  //用于保存带有子路由的路由数据。

  让route=[]

  //遍历数据

  for(设I=0;i menuList.lengthi ) {

  //如果有子路由,就递归遍历,返回的数据保存为子路由。

  if (menuList[i].children menu list[I]. children . length 0){

  //获取路由的基本格式

  route=getRoute(menuList[i])

  //递归处理子路由数据,返回保存为路由的子路由。

  route . children=fnadddynamicmenroutes(menu list[I].儿童)

  //保存带有子路由的路由。

  routes.push(路由)

  }否则{

  //保存正常路由

  temp.push(getRoute(menuList[i])

  }

  }

  //返回路由结果

  return routes.concat(临时)

  }

  //返回路由的基本格式

  函数getRoute (item) {

  //路由基本格式

  让route={

  //路由的路径

  路径:item.url,

  //路由名称

  名称:项目名称,

  //路由所在的组件

  //component:(resolve)=require([`@/layout/index `],resolve),

  component:(resolve)=require([`@/view $ { item . curl } `],resolve),

  元:{

  id: item.id,

  图标:项目.图标

  },

  //路由的子路由

  儿童:[]

  }

  //返回路线

  返回路线

  }

  这里有两个函数,将采集到的数据处理成路由表数据,并转换成路由的形式。

  FnAddDynamicMenuRoutes用于递归菜单数据。GetRoute用于返回数据转换的路由格式。注释写的应该算是很详细了,主要讲一下思路:

  遍历数据,并定义两个数组(temp,route)。temp用于保存没有子路由的路由,route用于保存有子路由的路由。如果某些数据有子路由,则遍历子路由,并将返回的结果作为当前数据的子路由。并使用route保存路线。如果有些数据没有子路由,直接用temp保存路由。最后返回两者拼接的结果,也就是转换后的数据。route 格式一般如下:

  路径:指路由路径(可以根据路径定位路由)。名称:指路线名称(根据路线名称可以定位路线)。组件:指路线所在的组件。子路由:指路由组件中嵌套的子路由。Meta:用于定义路由的一些元信息。这里有个大洞!配置组件时,需要动态导入组件,即vue异步组件。请参见以下文档。

  有两种导入方法,import和require。这里,简单地说,

  1导入属于es6导入模式,只支持静态导入。也就是说不能用变量或者表达式,只能用字符串。

  2 require属于commonJS模式,可以支持动态导入。不过在我的尝试中,我可以使用``模板字符串模式,似乎不能直接使用变量。这里尽量拼接字符串,而不是用变量替换拼接的字符串!

  因为import不支持动态导入,所以作者采用了require的方法,webpack文档中有这样一段话。

  综上所述,换句话说,组件的导入可以通过字符串拼接和模板字符串来完成(字符串包含变量),但是使用模板字符串导入时不能只使用变量!您必须指定一个目录,而不是所有变量!

  //字符串拼接模式

  组件:导入( @/view /sys/user )

  //模板字符串模式,webpack4版本需要使用require模式,注意` @ $ {item.curl } `,不行!您必须指定一个目录,而不是所有变量。

  component:(resolve)=require([`@/view $ { item . curl } `],resolve),

  这种现象其实和webpack import()的实现高度相关。因为webpack需要单独打包import()的所有模块,所以webpack会在工程打包阶段收集依赖关系。

  此时,webpack将找到import()的所有调用,并将传入的参数处理成一个规则,例如:

  导入(。/app path /util)=/^\.\/app。*\/util$/

  也就是说,导入参数中的所有变量都将被替换为[。*],webpack会根据这个规则找到所有符合条件的包,并打包成包。

  所以动态导入的正确姿势应该是尽可能静态的表示包的路径,尽量减少变量控制的区域。

  3.对于处理动态路由数据的函数,需要在正确的位置调用它才能发挥作用。此时,您需要使用beforeEach。在router/permission.js文件中配置导航卫士,每次路由跳转前可以做一些操作。在这里,您可以获得动态路线。

  从“@/router/index”导入路由器

  导入 element-ui/lib/theme-chalk/index . CSS

  导入 @ fortawesome/font awesome-free/CSS/all . min . CSS

  从“NProgress”导入nprogress

  导入 nprogress/nprogress.css

  从“@/router/getasyncprouter”导入{ fnAddDynamicMenuRoutes }

  从“@/api/sys/Menu”导入{getRouter}

  从“@/store”导入商店

  NProgress.configure({

  缓解:“缓解”,//动画模式

  速度:500,//增加进度条的速度

  ShowSpinner: false,//是否显示加载ico

  TrickleSpeed: 200,//自动递增间隔

  最小值:0.3 //初始化时的最小百分比

  })

  //白名单

  const whiteList=[/login] //无重定向白名单

  //导航保护装置

  router.beforeEach((收件人,发件人,下一个)={

  NProgress.start()

  尝试{

  //判断是否获取了动态菜单。如果没有,你需要一次性获得。

  if(store . getters . dynamic routes . length===0){

  if (whiteList.indexOf(to.path)!==-1) {

  下一个()

  }否则{

  getRouter()。然后(res={

  if (res.code===0) {

  let menu router=fnadddynamicmenroutes(RES . data[0])。儿童)

  store.dispatch(应用程序/动态路由,菜单路由)。然后(()={

  router . add routes(store . getters . dynamic routes)

  下一个({.到,替换:true})

  })

  }否则{

  Console.log(未能获取动态路由!)

  下一步({path: /login})

  }

  })

  }

  }否则{

  //路由已经存在或已被缓存。

  if (to.meta.requireAuth) {

  if(session storage . getitem( log in name )!==null) {

  //确定本地是否存在令牌。

  下一个()

  }否则{

  //如果没有登录,跳转到登录页面。

  下一步({path: /login})

  }

  }否则{

  if (whiteList.indexOf(to.path)!==-1) {

  下一个()

  }否则{

  if(session storage . getitem( log in name )!==null) {

  //确定本地是否存在令牌。

  下一个(`/?redirect=${to.path} `)

  }否则{

  下一个(`/登录?redirect=${to.path} `)

  }

  }

  }

  }

  } catch(错误){

  Console.log(“错误”)

  下一个(`/登录?redirect=${to.path} `)

  }

  })

  router.afterEach(()={

  //在进入新页面组件之前关闭进度条。

  NProgress.done()

  })

  注释写的比较详细了,主要说下思路:

  首先,确定获取动态菜单数据的时机。一般登录成功跳转到主页面,就获得了动态菜单数据。

  因为涉及到路线的跳转(登录页面-主页面),所以可以使用beforeEach来守护路线导航。但是,每一次路由跳跃都会在彼此之前触发,因此为了防止频繁获取动态路由值,所获取的路由信息以vuex模式存储在这里。如果已经采集到路线,直接跳转,否则采集动态菜单数据并处理一次。如果不使用vuex,可以保存在sessionStorage中。简而言之,您可以保存已获取的路由信息,以避免重复获取。

  4我们来看看store的写法。

  常量状态={

  动态路由:[]

  }

  常量突变={

  动态_路由(状态,路由){

  state.dynamicRoutes=路线

  }

  }

  常量操作={

  动态路由({提交},路由){

  提交(“动态路线”,路线)

  }

  }

  注意:Vue是单页应用,所以页面一刷新就会丢失一些数据,所以我们需要将数据存储在本地的store中,以保证路由不会丢失。

  至此,动态路由已经配置完毕。总的来说不是很难,主要是有坑!但是一旦理清思路,写代码就清楚了。

  

说一些笔者遇到的问题

  1.首先,组件的动态导入问题。因为webpack的版本不一样,所以需要通过导入的方式导入,根据情况需要。如果导入不正确,大部分都会报错,找不到模块。或者没有报错,但是路由跳转是一个空白页。如果导入正确,会跳转到正常;否则请找正确的导入方法!如果路线跳对了,能跳的组件都能显示出来,就完成一大半了!

  2.路由跳转的地方,因为我们的项目采用的是带二级菜单的左侧菜单栏,所以在路由正常跳转的时候,需要确定路由跳转的渲染位置是否正确!

  

后记

  刷新页面时出现问题,动态路由表会随着vuex的刷新而消失。

  处理:这里在刷新app.vue页面时,使用sessionStorage来存储store,防止刷新时vuex丢失。

  如下所示:

  导出默认值{

  名称:“应用程序”,

  已创建(){

  //加载页面时读取sessionStorage中的状态信息

  if(session storage . getitem( storeData ){

  这个。$ store . replace state(object . assign({ },this。$store.state,JSON . parse(session storage . getitem( storeData )))

  }

  //刷新页面时将vuex中的信息保存到sessionStorage。

  window . addevent listener( before unload ,()={

  session storage . setitem( storeData ,JSON.stringify(this。$store.state))

  })

  //与iphone兼容

  window . addevent listener( page hide ,()={

  session storage . setitem( storeData ,JSON.stringify(this。$store.state))

  })

  }

  }

  另外,成功登录后,获得了动态路由。这样刷新的时候路线就不会丢了!

  //获取动态路由

  getRouter()。然后(res={

  if (res.code===0) {

  let menu router=fnadddynamicmenroutes(RES . data[0])。儿童)

  store.dispatch(应用程序/动态路由,菜单路由)。然后(()={

  router . add routes(store . getters . dynamic routes)

  })

  console . log(store . getters . dynamic routes)

  }否则{

  Console.log(未能获取动态路由!)

  router.push(/login )

  }

  })

  以上个人经历,希望能给大家一个参考,也希望大家多多支持我们。

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: