一、Vue-Router基本使用
1.1 安装
- npm install vue-router
1.2 使用
-
创建路由需要映射的组件(打算显示的页面)
-
通过createRouter创建路由对象,并且传入routes和history模式
-
配置路由映射: 组件和路径映射关系的routes数组
-
创建基于hash或者history的模式
import { createRouter, createWebHashHistory } from 'vue-router' import Home from '../views/Home.vue'; import About from "../views/About.vue"; const router = createRouter({ // 哈希模式 history: createWebHashHistory(), routes: [ { path: '/home', component: Home }, { path: '/about', component: About } ] }) export default router -
-
使用app注册路由对象(use方法)
import { createApp } from 'vue' import router from './router' import App from './App.vue' createApp(App).use(router).mount('#app') -
路由使用: 通过
<router-link>和<router-view><div class="app"> <div class="nav"> <router-link to="/home">首页</router-link> <router-link to="/about">关于</router-link> </div> <router-view></router-view> </div>
二、Vue-Router基础
2.1 默认路径
- redirect重定向
{ path: '/', redirect: '/home' }
2.2 history模式
- createWebHashHistory() 哈希模式
- createWebHistory() history模式
2.3 router-link其他属性
- to
- 跳转的路径,可以是字符串或者一个对象
<router-link :to="{ path: '/home' }" replace>首页</router-link>
- replace
- 跳转替换不能够返回
- active-class
- 设置激活a元素后应用的class,默认是router-link-active
- exact-active-class
- 链接精准激活时,应用于渲染的
<a>的 class,默认是router-link-exact-active
- 链接精准激活时,应用于渲染的
2.4 路由懒加载-分包处理
-
当打包构建应用时,JavaScript 包会变得非常大,影响页面加载:
-
如果能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,这样就会更加高效
-
也可以提高首屏的渲染效率
-
-
Vue Router默认就支持动态来导入组件:
-
这是因为component可以传入一个组件,也可以接收一个函数,该函数 需要放回一个Promise
-
而import函数就是返回一个Promise
// 路由的懒加载 // webpack打包分包会使用下面的名字开头 const Home = () => import(/* webpackChunkName: 'home' */'../views/Home.vue') const About = () => import(/* webpackChunkName: 'about' */'../views/About.vue') -
2.5 其他属性
-
name:路由记录独一无二的名称
-
meta:自定义的数据
{ name: 'home', path: '/home', component: () => import('../views/Home.vue'), meta: { title: '首页', auth: true } },
三、Vue-Router进阶
3.1 动态路由使用
- path:
/user/:id
- 获取动态路由的值
-
在template中,直接通过
$route.params获取值; -
在created中,通过
this.$route.params获取值; -
在setup中,使用 vue-router库给我们提供的一个hook useRoute
- 该Hook会返回一个Route对象,对象中保存着当前路由相关的值
import { useRoute } from 'vue-router' const route = useRoute() console.log(route.params.id)
-
3.2 NotFound页面匹配
- path:
/:pathMatch(.*)*
-
对于没有匹配到的路由,通常会匹配到固定的某个页面(比如404或NotFound)
- 在错误页面中,可以编写一个动态路由用于匹配所有的页面
{ path: '/:pathMatch(.*)*', component: () => import('../views/NotFound.vue') }, -
可以通过
$route.params.pathMatch获取到传入的参数/:pathMatch(.*)和/:pathMatch(.*)*的区别在于$route.params.pathMatch解析的时候是否解析
3.3 路由的嵌套使用
- 在一层路由中添加 children属性:
children: [ { path: '/home', redirect: '/home/recommend' }, { path: 'recommend', // /home/recommend component: () => import('../views/HomeRecommend.vue') }, { path: 'ranking', // /home/ranking component: () => import('../views/HomeRanking.vue') } ] - 在Home组件中添加
<router-view> - 路径跳转
<router-link>
3.5 编程式导航
3.5.1 跳转的方式
-
push(路径)
-
push({ path/query })
-
replace()
import { useRouter } from 'vue-router' const router = useRouter() function jumpToHome() { // router.push('/home') router.push({ // name: 'home' path: '/home' }) } function jumpToAbout() { // router.push('/about') router.push({ path: '/about', query: { type: 'common', id: '14704170413432' } }) }
3.5.2 页面的前进与后退
- back()
- 相当于 router.go(-1)
- forward()
- 相当于 router.go(1)
- go(number)
四、Vue-Router高级
4.1 动态管理路由
4.1.1 什么情况下需要动态管理路由
- 后台管理系统:根据不同的角色生成不同的菜单
- 方案一:对应的菜单路由注册,路由守卫拦截
- 方案二:路由动态注册
4.1.2 动态添加路由
-
router.addRoute({})
-
router.addRoute("name", {})
// 一级路由 router.addRoute({ path: '/admin', component: () => import('../views/Admin.vue') }) // 添加二级路由 router.addRoute('home', { path: 'vip', component: () => import('../views/HomeVip.vue') })
4.1.3 管理路由别的方法
-
移除路由有以下三种方式:
- 方式一:添加一个name相同的路由
- 方式二:通过removeRoute方法,传入路由的名称
- 方式三:通过addRoute方法的返回值回调
// 方式1 router.addRoute({ path: '/about', name: 'about', component: About }) // 这将会删除之前已经添加的路由,因为他们具有相同的名字且名字必须是唯一的 router.addRoute({ path: '/other', name: 'about', component: Other }) // 方式2 router.addRoute({ path: '/about', name: 'about', component: About }) // 删除路由 router.removeRoute('about') // 方式3 const removeRoute = router.addRoute(routeRecord) removeRoute() // 如果路由存在的话删除路由 -
router.getRoutes()
- 获取一个包含所有路由记录的数组
-
router.hasRoute()
- 检查路由是否存在
4.2 路由导航守卫
4.2.1 beforeEach
-
vue-router 提供的导航守卫主要用来通过跳转或取消的方式守卫导航
-
全局的前置守卫beforeEach是在导航触发时会被回调的:
-
两个参数:
-
to:即将进入的路由Route对象
-
from:即将离开的路由Route对象
-
-
返回值:
-
false:取消当前导航
-
不返回或者undefined:进行默认导航
-
返回一个路由地址
-
可以是一个string类型的路径
-
可以是一个对象,对象中包含path、query、params等信息
-
-
可选的第三个参数:next(不推荐使用)
-
在Vue2中通过next函数来决定如何进行跳转的
-
在Vue3中通过返回值来控制的,不再推荐使用next函数,这是因为开发中很容易调用多次next
-
-
-
应用场景:
- 跳转订单时, 判断用户是否登录
- 没有登录:
- 调到登录页面
- 进行登录的操作
- 保存了token
- 登录成功:
- 跳到order页面
// 进行任何的路由跳转之前,传入到beforeEach中的函数都会被回调 router.beforeEach((to, from) => { // 进入所有页面都跳转登录页面 // if(to.path !== '/login') { // return '/login' // } const token = localStorage.getItem('token') if(to.path === '/order' && !token) { return '/login' } // console.log(to, from) })
4.2.2 路由导航的流程解析
-
Vue-Router还提供了很多的其他守卫函数,目的都是在某一个时刻给予回调,可以更好的控制程序的流程或者功能:
-
完整的导航解析流程:
-
导航被触发。
-
在失活的组件里调用
beforeRouteLeave守卫。 -
调用全局的
beforeEach守卫。 -
在重用的组件里调用
beforeRouteUpdate守卫(2.2+)。 -
在路由配置里调用
beforeEnter。 -
解析异步路由组件。
-
在被激活的组件里调用
beforeRouteEnter。 -
调用全局的
beforeResolve守卫(2.5+)。 -
导航被确认。
-
调用全局的
afterEach钩子。 -
触发 DOM 更新。
-
调用 beforeRouteEnter 守卫中传给 next 的回调函数,创建好的组件实例会作为回调函数的参数传入。
-