vue-router@4

一,前言

1.Vue RouterVue.js 的官方路由库,vue全家桶成员之一

2.使用 npm install vue-router@4 安装


二,项目配置

vue项目中,配置vue-router分为两个步骤
(1)初始化路由对象
(2)挂载路由

1.初始化路由对象

(1)createRouter 用于初始化路由对象,接受一个选项对象作为参数

(2)初始化路由最重要的是配置routes来确定整个项目的路由匹配规则

import { createRouter, createWebHashHistory } from "vue-router";

export default createRouter({
  history: createWebHashHistory(),//hash模式
  routes:[{ path: "/", component: Login }]//路由配置规则数组
})

2.挂载路由

(1)使用app.use()将创建的路由对象挂载到全局中,

(2)挂载之后,我们可以在全局中使用$router$route<router-view/><router-link/> 这些api

import { createApp } from 'vue'
import router from './router/index.js'
import App from './App.vue'
const app = createApp(App)
app.use(router)

三,路由匹配规则配置

1.vue-router中,路由匹配规则这个概念是非常重要,它表示了路由和组件的映射,通过routes字段配置。

2.一个最基础的路由配置如下,path表示路径,component表示对应的组件

  routes:[{ 
  	path: "/", //路径
   	component: Login, //匹配组件
   	}]

四,视图容器

1.vue-router内置组件<router-view>用于是用于承载路由跳转的容器,组件能展示出来,离不开<router-view>

2.注意,router-view上的组件因路由匹配规则切换时,组件会经历卸载到挂载完整的生命周期


通过项目配置,路由配置规则配置,和视图容器已经完成了最基本的路由跳转


五,视图容器的组织方式

1.视图的组织可以分两种,一种是嵌套关系,一种是平铺关系
在这里插入图片描述

2.这涉及到vue-router知识点,路由嵌套和命名视图

六,路由嵌套

1.要实现路由嵌套,首先要配置相应的规则,vue-router的路由嵌套关系,是通过children实现的

routes: [
  {
    path: "/layout", //路径
    component: Layout, //匹配组件
    children: [
      { path: "A", component: A }, //只匹配/layout/A
      { path: "B", component: B }, //只匹配/layout/B
      { path: "/C", component: C }, //匹配/C 等同于/layout/C
    ],
  },
];

2.在上面路由规则中,/layout 将会匹配到Layout组件,设Layout组件内部有一个router-view,通过路由/layout/A , 将会把A组件渲染至内部的router-view
在这里插入图片描述

3.children 配置只是另一个路由数组,就像 routes 本身一样。因此,可以根据自己的需要,不断地嵌套视图。

4.注意/ 开头的嵌套路径将被视为根路径。如果添加了/ 我们可以直接通过/C来访问到嵌套关系,而不必使用/layout/C,换句话说/C 等于/layout/C

5.注意,当访问/layout时,内部router-view 是不会有任何渲染的,因为匹配不到,假如我们想有一个默认视图,可以通过设置一个空路由

routes: [
  {
    path: "/layout",
    component: Layout,
    children: [
      { path: "", component: A }, //默认展示空路由
      { path: "B", component: B }, //只匹配/layout/B
    ],
  },
];

七,命名视图

1.同路由嵌套,想实现布局关系,首先也要配置相应的规则,vue-router的路由嵌套关系规则是通过components实现的,注意后面的s

routes: [
  {
    path: "/layout", 
    components: {
    	default: Home,
    	leftSide: LeftSide,
    	rightSide: RightSide
	}, 
 	
  },
];

2.之后我们通过属性name为视图容器命名,来组织我们的布局结构

<div>
	<router-view name="leftSide"/>	
	<router-view/>  <!--没有name的默认名为default-->
	<router-view name="rightSide"/>
</div>

3.当我们访问/layout就能渲染出相应的结构

4.注意命名视图里的某个容器是不支持路由切换的,要想实现这个效果,可以借助vue内置组件component 配合路由的不同的参数,来渲染不同的组件。


八,路由跳转

vue-router提供了两种方式来触发路由跳转

(1)声明式
(2)编程式

1.声明式

(1)声明式是以内置组件<router-link> 来进行跳转

2.编程式

(1)编程式是以api形式进行跳转,api被挂载在vue2$router,和vue3useRouter

(2)编程式导航api如下

api介绍
pushrouter.push会向 history 栈添加一个新的记录,所以,当用户点击浏览器后退按钮时,会回到之前的 URL
replacerouter.replace导航时不会向 history 添加新记录,而是取代了当前的条目,replace调用后返回的是一个promise,当成功跳转时执行.then,跳转失败时执行.catch,例如如果我们在导航守卫时拒绝页面跳转时,此时就会执行.catch
backrouter.back用于返回上一条记录
forwardrouter.forward用于前进到下一条记录
gorouter.go用于横跨历史,router.go(-1) 等于router.back()router.go(1) 等于router.forward()

(3)其中使用频率最高的就是pushreplacepushreplace使用方法相似,接受一个选项对象

push({
	path:"/demo" //跳转路径
	name:"demo" //对于具名路由,可以使用name字段来跳转
	params:{id:"xxx"} //传递动态参数,注意params不能同时和path使用,要传递动态参数时,可以选择具名路由
	query:{id:"xxx"} //传递查询参数,是url上?后的参数
	...
})

(4)注意,当使用push跳转相同页面时,vue-router默认不会重复添加相同的路由,这导致改变参数也不能生效,比如说我们正处于一个user页面,这时我们要在推一个携带不一样的参数user页面,直接使用push是推不进去的,解决方法如下

//跳转时携带时间参数
this.$router.push({
      name: 'download',
       query: {
           type: this.checkedType,
           label: this.checkedLabel,
           t: Date.now()
       }
   })
   
//给视图容器加个key,让vue知道,这是不同组件
<router-view :key="$route.path + $route.query.t">
</router-view>

九,路由跳转传参

vue-router路由跳转传递参数有两种

(1)动态参数 params
(2)查询参数 query

1.动态参数

(1)动态参数首先需要在路由规则配置时显式配置,在path后使用

routes:[
	//这里name即为动态参数
	{path:'/user/:name',component:User}
]

(2)对于编程式跳转方式,我们在pushrepalce方法的params里传递

import { useRouter } from 'vue'
const router = useRouter()
router.push({
	path:'/user'
	params:{ name:'LL'}
}) 

//最终形成的路由: /user/LL

(3)在跳转的页面上,我们可以通过$route.paramsvue2)或useRoute.paramsvue3)获取到传递的动态参数

$route.params  //{name:lin}

//在setup中
import { useRoute } from 'vue-router'
const route = useRoute()
route.params   //{name:lin}

2.查询参数

(1)不同于动态参数,查询参数的使用不需要配置,

(2)对于编程式跳转方式,我们在pushrepalce方法的query里传递

import { useRouter } from 'vue'
const router = useRouter()
router.push({
	path:'/user'
	query:{ name:'LL'}
})

//最终形成的路由: /user?name=LL

(3)在跳转的页面上,我们可以通过$route.queryvue2)或useRoute.queryvue3)获取到传递的动态参数

$route.query//{name:lin}

//在setup中
import { useRoute } from 'vue-router'
const route = useRoute()
route.query//{name:lin}

十,命名路由

1.在配置路由的时候,我们可以通过配置name选项,来为路由命名。

  routes:[{ 
  	path: "/login", //路径
  	name:'login',
   	component: Login, //组件
   	}]

2.配置了命名路由后,我们不仅可以通过path来跳转,也可以用name来跳转,如下,注意当使用动态参数传递时,对于编程式导航必须借助于命名路由进行跳转

router.push({ name: 'login'})

// 如果可能的话,使用 `name` 和 `params` 从自动 URL 编码中获益
router.push({ name: 'user', params: { username } }) // -> /user/eduardo
// `params` 不能与 `path` 一起使用,否则会忽略params
router.push({ path: '/user', params: { username } }) // -> /user
<router-link :to="{ name: 'login'}">
  Login
</router-link>

3.所有路由的命名都必须是唯一的。如果为多条路由添加相同的命名,路由器只会保留最后那一条

十一,路由守卫

1.在vue-router中守卫可以分为3种

(1)全局守卫
(2)路由守卫
(3)组件守卫

2.全局守卫

(1)全局前置守卫:router.beforeEach

接受(tofromnext)参数tofrom是标准的路由对象
.
返回false,取消本次导航
返回trueundefined,则导航是有效的,并调用下一个导航守卫
返回一个标准的路由对象,相当于调router.push,会中断当前的导航,同时用相同的 from 创建一个新导航

 router.beforeEach(async (to, from) => {
 	if(没有权限){ //取消本次导航
 		return false
 	}
 	if(有权限 && 还未获取token){ //重定向
		return { name: 'Login' }
	}else{ //导航有效
		return true
	}

(2)全局解析守卫:router.beforeResolve

router.beforeEach 类似,不同的是,解析守卫刚好会在导航被确认之前、所有组件内守卫和异步路由组件被解析之后调用
.
router.beforeResolve 是获取数据或执行任何其他操作(如果用户无法进入页面时你希望避免执行的操作)的理想位置
.
总的来说没有什么特别的,就是触发的时机不一样,我们可以进行一些不同的操作

(3)全局后置守卫:router.afterEach

接受(tofrom)参数 ,注意不接受next
.
afterEach也无法在改变导航本身,可以用于修改页面标题,分析页面等等

3.路由守卫

(1)beforeEnter

在进入路由时触发,且注意只有由不同的路由进入才触发,当使用动态路由时,动态参数的改变不会触发beforeEnter

function removeQueryParams(to) {
  if (Object.keys(to.query).length)
    return { path: to.path, query: {}, hash: to.hash }
}

function removeHash(to) {
  if (to.hash) return { path: to.path, query: to.query, hash: '' }
}

const routes = [
  {
    path: '/users/:id',
    component: UserDetails,
    beforeEnter: [removeQueryParams, removeHash],
  },
  {
    path: '/about',
    component: UserDetails,
    beforeEnter: [removeQueryParams],
  },
]

4.组件守卫

(1)beforeRouteEnter

在渲染该组件的对应路由被验证前调用
不能获取组件实例 this
因为当守卫执行时,组件实例还没被创建
.
该导航守卫接受第三个参数next,且是唯一一个守卫next接受一个参数作为回调函数,并把组件实例作为回调方法的参数

(2)beforeRouteUpdate

在当前路由改变,但是该组件被复用时调用
举例来说,对于一个带有动态参数的路径 /users/:id,在 /users/1/users/2 之间跳转的时候,
由于会渲染同样的 UserDetails 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
因为在这种情况发生的时候,组件已经挂载好了,导航守卫可以访问组件实例 this

(3)beforeRouteLeave

在导航离开渲染该组件的对应路由时调用,与 beforeRouteUpdate 一样,它可以访问组件实例 this
.
这个 离开守卫 通常用来预防用户在还未保存修改前突然离开。该导航可以通过返回 false 来取消

5.各个守卫执行顺序

(1)导航被触发
(2)失活组件触发beforeRouteLeave
(3)全局前置守卫beforeEach触发
(4)被复用组件触发beforeRouteUpdage
(5)在路由配置里调用beforeEnter
(6)解析异步路由组件
(7)被激活的组件触发beforeRouteEnter
(8)调用全局的 beforeResolve
(9)导航被确认
(10)触发后置守卫afterEach
(11)触发 DOM 更新。
(12)触发beforeRouteEnter的传给next的回调函数,创建好的组件实例会作为回调函数的参数传入。

十二,路由配置优化

1.组件静态配置,当打包构建应用时,JavaScript 包会变得非常大,影响页面加载

import Login from './login.vue
 createRouter {
  history: createWebHashHistory(),//hash模式
  routes:[{ 
  	path: "/", //路径
  	redirect:"/login", //重定向 
   	component: Login, //组件
   	},]
}

2.组件动态配置:把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,这样就会更加高效

const Login = ()=>import('./index.vue')
 createRouter {
  history: createWebHashHistory(),//hash模式
  routes:[{ 
  	path: "/", //路径
  	redirect:"/login", //重定向 
   	component: Login, //组件
   	},]
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值