Vue3路由新特性(Vue-Router3和Vue-Router4对比总结)

2,523 阅读6分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第6天,点击查看活动详情

简介

前面笔者写了对比Vue2总结Vue3新特性(2022年最全,2.5w字!)一文,里面详细讲述了Vue3的一些新特性,感兴趣的小伙伴可以看看。今天我们继续来说说Vue3路由。

我们都知道在vue2中配套使用的路由是vue-router@3.xvue3中配套使用的路由是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

路由跳转

由于vue3setup方法没有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.$routerthis.$route。只是在组合式写法setup函数中不支持而已。

在模板中我们仍然可以访问 $router 和 $route,所以不需要在 setup 中返回 router 或 route

路由参数

由于vue3setup方法没有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.$routerthis.$route。只是在组合式写法setup函数中不支持而已。

在模板中我们仍然可以访问 $router 和 $route,所以不需要在 setup 中返回 router 或 route

路由钩子函数

vue3中有改动的路由钩子是组件内钩子。

vue2中有beforeRouteEnterbeforeRouteUpdatebeforeRouteLeave三个钩子。但是在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 的话,其实还是可以使用beforeRouteEnterbeforeRouteUpdatebeforeRouteLeave这三个钩子的。但是如果是使用 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 和 sensitivevue3新增的,主要用来控制路由的匹配规则。

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字!)

Vux4新特性(Vuex3和Vuex4对比总结)

后记

感谢小伙伴们的耐心观看,本文为笔者个人学习笔记,如有谬误,还请告知,万分感谢!如果本文对你有所帮助,还请点个关注点个赞~,您的支持是笔者不断更新的动力!