一、路由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 >

三、< route-link >属性及其它介绍

  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的错误页面中,可以编写一个动态路由用于匹配所有的页面:

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

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

五、路由嵌套/子路由

{
	path:'/home',
	component:Home,
	children:[
		{path:'',redirect:'/home/product'},
		{path:'producedetail',redirect:'/home/producedetail'},
	]
}

六、路由传参

1、方式一:query

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

2、方式二:params

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、方式三:标签传参

// 标签传参
< 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、方式四:路由配置

{
	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之前执行。

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

3、路由使用

//src/router/index.ts(全局守卫)
	//...
export const router = createRouter({
	//...
});
router.beforeEach((to,from,next)=>{
	next();
})
...beforeResolve...
...afterEach...


// 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选项要求的数组。
// routes选项
{
	path:'',
	name:'',
	component:'',
	meta:{title:"",icon:"",role:[]},
	children:[]
}

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

  • 加载静态路由,用户能直接访问的路由,不需要判断权限就能直接展示的;
  • 加载动态路由,需要判断用户权限,需要从后台传过来,需要动态动态生成菜单的。
    == 静态路由 ==:创建src/router/default.js;一般是首页,登录页,404,没有权限;
    == 动态路由 ==:什么时候注册?在哪里注册?怎么注册?登录之后注册;在路由守卫里面注册,用router.addRoute()一个个加进去。
// 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');
	}
})
...

如何动态注册?

@/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相同的路由;

router.addRoute({path:'about',name:'about',component:'About'})

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

router.removeRoute('about')

九、Vue3中引入router

import { useRoute, useRouter } from 'vue-router';
const route = useRoute();
const router =  userRouter();
// 相当于vue2中的this.$route,this.$router
Logo

基于 Vue 的企业级 UI 组件库和中后台系统解决方案,为数万开发者服务。

更多推荐