持续创作,加速成长!这是我参与「掘金日新计划 · 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 这两个钩子函数的。
过渡效果
<Transition> 是一个内置组件,这意味着它在任意别的组件中都可以被使用,无需注册。它可以将进入和离开动画应用到通过默认插槽传递给它的元素或组件上。进入或离开可以由以下的条件之一触发:
- 由
v-if所触发的切换 - 由
v-show所触发的切换 - 由特殊元素
<component>切换的动态组件 - 改变特殊的
key属性
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。
savedPosition 是 Vue Router 里 scrollBehavior 的一个参数,专门用来处理 浏览器前进/后退按钮的滚动位置恢复。当用户在浏览器里点击 后退或前进,页面会想要恢复之前的滚动位置,这时 Vue Router 会把上一次的滚动位置传给 scrollBehavior 的 savedPosition 参数。
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字!)
后记
感谢小伙伴们的耐心观看,本文为笔者个人学习笔记,如有谬误,还请告知,万分感谢!如果本文对你有所帮助,还请点个关注点个赞~,您的支持是笔者不断更新的动力!