vue-router

Vue3路由详情(vue-router)

一、路由vue-router说明

1.createWebHashHistory(process.env.BASE.URL):hash路由

2.createWebHistory:history路由

3.createMemoryHistory:带缓存history路由

4.parseQuery:查询参数反序列化

5.stringfiyQuery:查询参数序列化

6.onBeforeRouteLeave:路由离开钩子

二、路由使用

1.切换触发:

< router-link to="/home">Home</ router-link >

2.显示< router-view >< /router-view >

  1. to:字符串/对象;
  2. replace:设置成replace属性的话,当点击时,会调用router.replace(),而不是router.push();
  3. active-class:设置激活a元素后应用的class,默认是route-link-active;
  4. exact-active-class:链接精准激活时,应用于渲染的< a >的class,默认是route-link-exact-active;

四、Not Found

Not Found:没有匹配到路由会展示的页面;

比如NotFound的错误页面中,可以编写一个动态路由用于匹配所有的页面:

typescript 复制代码
{
	path:'/:pathMatch(.*)',
	component:()=>import ('@/view/NotFound.vue');
}

可以通过$route.params.pathMatch获取传入的参数,匹配规则加 * : path:'/:pathMatch(.*)'。

五、路由嵌套/子路由

typescript 复制代码
{
	path:'/home',
	component:Home,
	children:[
		{path:'',redirect:'/home/product'},
		{path:'producedetail',redirect:'/home/producedetail'},
	]
}

六、路由传参

1、方式一:query

typescript 复制代码
router.push({
	path:'/about',
	query:{name:'张三'}
})
// 通过$route.query获取参数
// query传参:参数会显示在地址,F5刷新不会清空

2、方式二:params

typescript 复制代码
router.push({
	name:'About',
	params:{name:'张三',age:18}
})
// 通过$route.params获取参数
// params传参:参数不会显示在地址,F5刷新会清空


// 注意:src/routes/index.ts
[
	{
		path:'/about',
		name:'About',// 一定要写,params通过name识别路径
		component:About
	}
]

3、方式三:标签传参

typescript 复制代码
// 标签传参
< router-link :to="{path:'/login',query:{name:'张三'}}">Home</ router-link >
< router-link :to="{name:'About',params:{name:'李四'}}">About</ router-link >
// 接受参数
this.$route.query
this.$route.params

4、方式四:路由配置

typescript 复制代码
{
	path:'/about/:id',
	name:'About',
	component:About
}
// 通过$route.params获取参数

//或

this.$router.push({
	path:'/about/:id',
})

七、路由导航守卫(7个钩子函数)

1、基础介绍

一共7个钩子函数,除了afterEach没有next参数,只有to,from,其他的钩子函数都有to,from,next3个参数。

to :即将进入的目标路由;

from:即将离开的路由;

next:是一个函数,一定要调用这个函数来resolve钩子函数。否则不能正常切换路由。

注意:参数或查询的改变并不会触发进入/离开组件的导航守卫(beforeRouteEnter、beforeRouteLeave)

2、7个导航守卫函数介绍

2-1 全局守卫

beforeEach:全局前置守卫

①地址栏发生变化就会触发,不管组件是否复用;

②创建多个beforEach时会按照顺序触发,不会覆盖;

③必须执行next函数;

④它在beforeResolve执行前执行;

beforeResolve:全局解析守卫

①同上①

②在beforeEach执行之后执行,在所有的组件守卫执行完成后执行;

afterEach:全局后置钩子(不含next)

①同上①

④它在beforeEach、beforeResolve执行后执行;

2-2 组件守卫(在组件中定义)

beforeRouteEnter

①该函数在进入该组件时执行,一般是通过导航变化然后进入组件时执行,如果只是组件复用是不执行该函数的;

②该函数中没有this,因为该函数执行时组件实例还没有创建,不可以通过调用next函数中回调函数,回调函数的第一个参数就是该组件的实例,不过回调函数是异步时,他需要等到组件实例创建完后再调用该回调函数执行;

③该函数执行晚于beforeEnter;

beforeRouteUpdate

①该函数只在组件发生复用时才执行,在第一次进入组件时不执行;

②该函数在beforeEach之后,在beforeResolve之前执行;

beforeRouteLeave

①该函数只有在离开该组件时执行,在组件复用时不执行;

②在通过导航进行组件间的切换时,一般先要执行即将离开的组件的beforeRouteLeave函数然后再执行全局beforeEach守卫;

2-3 独享守卫

beforeEnter

①只有进入对应路由时才会执行,组件复用说明是同一个路由间的导航切换,不会触发;

②函数在beforeEach之后执行,在beforeRrouteEnter之前执行。

typescript 复制代码
[
	{
		path:'/about',
		name:'About',
		component:About,
		beforeEnter(to,from,next){
			if(to.path=='test'){
				next();
			}else{
				next();
			}
		}
	}
]

3、路由使用

typescript 复制代码
//src/router/index.ts(全局守卫)
	//...
export const router = createRouter({
	//...
});
router.beforeEach((to,from,next)=>{
	next();
})
...beforeResolve...
...afterEach...
typescript 复制代码
// src/views/About.vue(组件守卫)
<script lang="ts">
	import { definecomponent } from 'vue';
	export default definecomponent({
		name:'About',
		methods:{},
		beforeRouteEnter(to,from,next){
			next();
		}
		...beforeRouteUpdate...
		...beforeRouteLeave...
		
	})
</script>

八、动态添加删除路由

1、vue-router动态路由及菜单实现

  • router.addRoutes(routes:Arrauy< RouteConfig >)
    动态添加的路由规则。参数必须是一个符合routes选项要求的数组。
typescript 复制代码
// routes选项
{
	path:'',
	name:'',
	component:'',
	meta:{title:"",icon:"",role:[]},
	children:[]
}

2./src/router/index.ts改造

  • 加载静态路由,用户能直接访问的路由,不需要判断权限就能直接展示的;
  • 加载动态路由,需要判断用户权限,需要从后台传过来,需要动态动态生成菜单的。
    == 静态路由 ==:创建src/router/default.js;一般是首页,登录页,404,没有权限;
    == 动态路由 ==:什么时候注册?在哪里注册?怎么注册?登录之后注册;在路由守卫里面注册,用router.addRoute()一个个加进去。
typescript 复制代码
// src/router/index.ts
...
import routeAssembler from './setup';
import  { hasAuthority } from '@/utils/login.js';
...
//路由守卫
let registerRouteFresh = true;// 是否动态加载过
router.beforeEach((to,from,next) => {
	const isLogin = localStorage.isLogin ? true : false;
	if ( isLogin ){
		// 已登录
		let isAccess = hasAuthority ( to.meta.access );
		if ( !isAccess ){// 没有权限
			next('/notAccess');
			return;
		}
		if ( registerRouteFresh ){//还没有动态加载过
			// 动态注册路由
			routeAssembler ( router );
			registerRouteFresh = false;
			next({...to,replace:true})
		}else{
			// 已经登录了,不能再打开登录页
			to.path === '/login'? next('/home'):next();
		}
	} else {
		// 如果无须登录则直接打开,否则转向登录页面
		to.meta.nologin || to.path === '/login'? next():next('/login');
	}
})
...

如何动态注册?

typescript 复制代码
@/router/setup.js
// 即上段代码中的routeAssember:
import fixItems from "./default"; // 默认路由
import {HomeName} from './default';// 统一命名首页路由页
import projectItems from '@/modules/router'; //具体业务系统的路由

export default (router)=>{
	//获取动态路由
	const dynaItems = getDynamicItems();
	//对齐首页(统一命名首页)
	adPatHome(HomeName,dynaItems);
	//添加动态路由
	dynaItems.forEach(value=>{
		router.addRoute(value);
	})
	//获取动态路由(后台)
	const getDynamicItems=()=>{
		//...从后端获取...
		return projdctItems
	}
	//默认路由与业务路由对齐首页的路由信息
	//所谓对齐,就是所有name保持一致,这样才能保证动态加入的路由项,覆盖掉前面path和name相同的路由。
	const adPatHome=(HomeName,dynaItems)=>{
	 let home = dynaItems.filter(item=>{
	 	return item.path === '/';
	 })
	 if(home.length >0 && home[0].name!==HomeName){
	 	home[0].name=HomeName;
	 }
	}
}

2、动态删除路由

== 方式一 == 添加一个name相同的路由;

typescript 复制代码
router.addRoute({path:'about',name:'about',component:'About'})

== 方式二 ==通过removeRoute方法传入路由名称;

typescript 复制代码
router.removeRoute('about')

九、Vue3中引入router

typescript 复制代码
import { useRoute, useRouter } from 'vue-router';
const route = useRoute();
const router =  userRouter();
// 相当于vue2中的this.$route,this.$router
相关推荐
z千鑫几秒前
【前端】详解前端三大主流框架:React、Vue与Angular的比较与选择
前端·vue.js·react.js
m0_7482561432 分钟前
前端 MYTED单篇TED词汇学习功能优化
前端·学习
小马哥编程2 小时前
Function.prototype和Object.prototype 的区别
javascript
小白学前端6662 小时前
React Router 深入指南:从入门到进阶
前端·react.js·react
苹果醋32 小时前
React系列(八)——React进阶知识点拓展
运维·vue.js·spring boot·nginx·课程设计
web130933203982 小时前
前端下载后端文件流,文件可以下载,但是打不开,显示“文件已损坏”的问题分析与解决方案
前端
王小王和他的小伙伴2 小时前
解决 vue3 中 echarts图表在el-dialog中显示问题
javascript·vue.js·echarts
学前端的小朱2 小时前
处理字体图标、js、html及其他资源
开发语言·javascript·webpack·html·打包工具
outstanding木槿2 小时前
react+antd的Table组件编辑单元格
前端·javascript·react.js·前端框架
好名字08213 小时前
前端取Content-Disposition中的filename字段与解码(vue)
前端·javascript·vue.js·前端框架