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的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。