持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第6天,点击查看活动详情
简介
前面笔者写了对比Vue2总结Vue3新特性(2022年最全,2.5w字!)一文,里面详细讲述了Vue3
的一些新特性,感兴趣的小伙伴可以看看。今天我们继续来说说Vue3
路由。
我们都知道在vue2
中配套使用的路由是vue-router@3.x
,vue3
中配套使用的路由是vue-router@4.x。
下面我们主要说说vue-router@4.x
相较vue-router@3.x
几个比较大的改动。也就是我们日常开发所必须要知道的点。
下面笔者用
vue2
代表vue-router@3.x
,用vue3
代表vue-router@4.x
来讲述,方便大家区分和理解。
创建
vue3
不再使用new Router()
创建实例,而是使用createRouter
方法。
并且路由模式也不是简单的传递history、hash、abstract
,而是通过createWebHistory、createWebHashHistory、createMemoryHistory
并传递base
来创建。
vue2 使用 new Router创建
import Vue from 'vue'
import Router from 'vue-router'
const routes = [
{
path: '/',
name: 'Home',
component: Home
}
]
Vue.use(Router)
const router = new Router({
base: process.env.BASE_URL,
mode: 'history',
scrollBehavior: () => ({ y: 0 }),
routes
})
export default router
vue3 使用 createRouter 创建
import { createRouter, createWebHistory } from 'vue-router'
import Home from '../views/Home.vue'
const routes = [
{
path: '/',
name: 'Home',
component: Home
},
]
const router = createRouter({
history: createWebHistory(process.env.BASE_URL),
routes
})
export default router
路由跳转
由于vue3
的setup
方法没有this
,所以不能再使用this.$router
获取路由对象啦。在vue3
中需要使用useRouter
方法。
vue2 使用 $router
跳转
export default {
mounted() {
this.$router.push()
this.$router.replace()
}
}
vue3 使用 useRouter
路由跳转
import { useRouter } fom vue-router
export default {
setup() {
const router = useRouter()
router.push()
router.replace()
}
}
请注意,在Vue-Router4
中并没有删除$router
和 $route
。
在Vue2
选项式写法中还是可以直接使用this.$router
和 this.$route
。只是在组合式写法setup
函数中不支持而已。
在模板中我们仍然可以访问 $router
和 $route
,所以不需要在 setup
中返回 router
或 route
。
路由参数
由于vue3
的setup
方法没有this
,所以不能再使用this.$route
获取当前路由对象啦。在vue3
中需要使用useRoute
方法。
vue2 使用 $route
获取参数
export default {
mounted() {
const {id} = this.$route.query
const {id} = this.$route.params
}
}
vue3 使用 useRoute 获取参数
import {useRoute} fom vue-router
export default {
setup() {
const route = useRoute()
const {id} = route.query
const {id} = route.params
}
}
请注意,在Vue-Router4
中并没有删除$router
和 $route
。
在Vue2
选项式写法中还是可以直接使用this.$router
和 this.$route
。只是在组合式写法setup
函数中不支持而已。
在模板中我们仍然可以访问 $router
和 $route
,所以不需要在 setup
中返回 router
或 route
。
路由钩子函数
在vue3
中有改动的路由钩子是组件内钩子。
在vue2
中有beforeRouteEnter
、beforeRouteUpdate
、beforeRouteLeave
三个钩子。但是在vue3
中移除了beforeRouteEnter
,只剩下两个组件内钩子函数。
vue2 组件内钩子有三个
// vue2中都必须显示调用next方法
beforeRouteEnter(to, from, next) {
console.log("beforeRouteEnter");
next();
},
beforeRouteUpdate(to, from, next) {
console.log("beforeRouteUpdate");
next();
},
beforeRouteLeave(to, from, next) {
console.log("beforeRouteLeave");
next();
},
并且在vue2
中,如果定义了路由钩子函数,就必须显示调用next()
方法,但在vue3
中就不需要显示调用next()
方法了。
vue3 移除了 beforeRouteEnter
import { onBeforeRouteLeave, onBeforeRouteUpdate } from 'vue-router'
export default {
setup() {
onBeforeRouteLeave((to, from, next) => {})
onBeforeRouteUpdate((to, from, next) => {})
}
}
其实说vue3 移除了 beforeRouteEnter
是不精准的,在 vue3
如果使用的是 选项式api
的话,其实还是可以使用beforeRouteEnter
、beforeRouteUpdate
、beforeRouteLeave
这三个钩子的。但是如果是使用 composition api
那就只能使用onBeforeRouteLeave、onBeforeRouteUpdate
这两个钩子函数的。
过渡效果
vue3
的过渡效果使用方式相对vue2
有了调整。
vue2 支持直接使用
在vue2
中,给路由加过渡效果我们只需要使用<transition>
包裹<router-view>
即可
<transition>
<router-view></router-view>
</transition>
vue3 需要借助 v-slot
作用域插槽
但是在vue3
中,需要使用如下方式
<router-view v-slot="{ Component }">
<transition name="fade">
<component :is="Component" />
</transition>
</router-view>
组件缓存
vue3
的组件缓存使用方式相对vue2
有了调整。
vue2 支持直接使用
在vue2
中,给路由加过渡效果我们只需要使用<keep-alive>
包裹<router-view>
并自定义配置即可。
<keep-alive>
<router-view></router-view>
</keep-alive>
vue3 需要借助 v-slot
作用域插槽
但是在vue3
中,需要使用如下方式,跟过渡效果的改动一样。
<router-view v-slot="{ Component }">
<keep-alive>
<component :is="Component" />
</keep-alive>
</router-view>
滚动行为
vue3
相对vue2
,滚动行为的功能没改变,只是改变了几个参数名。把vue2
返回的坐标点x、y
改成了top、left
,把选择器selector
改成了el
。
vue2 使用 x、y、selector
在vue2
中,我们是这样使用scrollBehavior
的
scrollBehavior (to, from, savedPosition) {
if (savedPosition) {
return savedPosition
} else {
// return { x: 0, y: 0 }
// return { selector: to.hash }
}
}
vue3 使用 top、left、el
在vue3
中,我们是这样使用scrollBehavior
的
scrollBehavior (to, from, savedPosition) {
if (savedPosition) {
return savedPosition
} else {
// return { top: 0, left: 0 }
// return { el: to.hash }
}
}
strict 和 sensitive
strict 和 sensitive
是vue3
新增的,主要用来控制路由的匹配规则。
vue2 只支持 caseSensitive
我们知道,在vue-router3
中,默认路由匹配是不区分大小写和尾/
的。
当我们的路由配置如下
{
path: "/home",
component: Home
}
那/home、/home/、/HOME、/HOME/
是都可以匹配到/home
的,也就是不区分大小写和尾/
。
但是可以通过caseSensitive
来配置是否严格区分大小写。
{
path: "/home",
component: Home,
caseSensitive: true
}
那只有/home、/home/
是可以匹配到/home
的,也就是不区分尾/
。
vue3 支持 strict 和 sensitive
但是在vue-router4
中新增了1个配置 strict
, 然后把caseSensitive
修改成sensitive
。
当配置strict
严格匹配尾/
。
{
path: "/home",
component: Home,
strict: true
}
那只有/home、/HOME
是可以匹配到/home
的,也就是不区分大小写。
当配置sensitive
的时候严格匹配大小写。
{
path: "/home",
component: Home,
sensitive: true
}
那只有/home、/home/
是可以匹配到/home
的,也就是不区分尾/
。
两个属性可以结合使用可以达到精准匹配的效果。
这两个属性默认值都是false
。也就是不配置跟以前的效果是一样的,不区分大小写和尾/
。
空 path
的命名子路由
在vue3
中带有空 path
的命名子路由不再自动添加斜线。
vue2 会自动创建/
在vue2
是不是有这种用法,就是子组件不写path
,导航或解析到命名的路由 dashboard
时会自动生成一个/
的path
。这样我们在浏览器输入/dashboard 或 /dashboard/
就会自动匹配到DashboardDefault
组件。
const routes = [
{
path: '/dashboard',
name: 'dashboard-parent',
component: DashboardParent,
children: [
{ path: '', name: 'dashboard', component: DashboardDefault },
{
path: 'settings',
name: 'dashboard-settings',
component: DashboardSettings,
},
],
},
]
vue3 不会自动创建/
现在,导航或解析到命名的路由 dashboard
时,会产生一个不带斜线的 URL:
在不配置strict
参数的情况下,我们在浏览器输入/dashboard 或 /dashboard/
还是会自动匹配到DashboardDefault
组件。这对路由页面的展示好像并没有影响。
但是对子级 redirect
有重要的副作用,如下所示:
const routes = [
{
path: '/parent',
component: Parent,
children: [
// 现在将重定向到 `/home` 而不是 `/parent/home`
{ path: '', redirect: 'home' },
{ path: 'home', component: Home },
],
},
]
上面的例子在vue2
中会重定向到/parent/home
,但是在vue3
中会重定向到/home
。
原因:这是为了使尾部的斜线行为保持一致:默认情况下,所有路由都允许使用尾部的斜线。可以通过使用 strict
配置和手动添加(或不添加)斜线来禁用它。
系列文章
对比Vue2总结Vue3新特性(2022年最全,2.5w字!)
后记
感谢小伙伴们的耐心观看,本文为笔者个人学习笔记,如有谬误,还请告知,万分感谢!如果本文对你有所帮助,还请点个关注点个赞~,您的支持是笔者不断更新的动力!