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
相关推荐
Pedantic6 小时前
SwiftUI 手势层级(Gesture Hierarchy)详解
前端
飘尘7 小时前
前端转型全栈(Java后端)的快速上手指引
前端·后端·全栈
一颗烂土豆7 小时前
Meshopt 压缩深度解析,为什么它比 Draco 更快
前端·javascript·webgl
浏览器工程师8 小时前
AI Agent 接浏览器任务,先别让它一路点到底
前端·后端
雨季mo浅忆8 小时前
VSCode自动格式化三要素
前端
爱勇宝9 小时前
深扒 Anthropic 1680 位工程师简历:应届生几乎没机会,AI 公司最缺的不是博士
前端·后端·程序员
kyriewen9 小时前
同事每天催我 Code Review,我写了个脚本让 AI 替我 review PR——现在他反过来催 AI 了
前端·javascript·ai编程
user205855615181312 小时前
Windows 项目安装时报 `node-sass` 错误,如何快速处理
前端
LiaCode12 小时前
Redis 在生产项目的使用
前端·后端
LiaCode12 小时前
一天学完 redis 的爽翻版核心知识总结
前端·后端