一、Vue2 与 Vue3 路由的区别
1. 创建路由实例方式的不同
-
Vue 2 中,通过
Vue.use()注册路由插件,并通过new VueRouter()来创建路由实例。
import Vue from 'vue';import VueRouter from 'vue-router';import Home from '@/components/Home.vue';Vue.use(VueRouter);const routes = [{ path: '/', component: Home }];const router = new VueRouter({routes});new Vue({router,render: h => h(App)}).$mount('#app');
Vue 3 中,通过 createRouter 和 createWebHistory 等 API 创建路由实例,直接使用 app.use() 挂载,不再需要 Vue.use() 来注册插件。
import { createApp } from 'vue';import { createRouter, createWebHistory } from 'vue-router';import Home from '@/components/Home.vue';import App from './App.vue';const routes = [{ path: '/', component: Home }];const router = createRouter({history: createWebHistory(),routes});const app = createApp(App);app.use(router);app.mount('#app');
2. 动态路由的添加方式
-
Vue 2 中使用
addRoutes()来动态添加多个路由,这个方法已经在 Vue 3 中被移除。
router.addRoutes([{ path: '/about', component: About }]);
Vue 3 中使用 addRoute() 来动态添加单个路由,且可以指定父级路由进行嵌套路由的动态添加。
router.addRoute({ path: '/about', component: About });router.addRoute('parent', { path: 'child', component: Child });
3. 路由守卫的变化
Vue 3 在组合式 API (setup) 中新增了 onBeforeRouteUpdate 和 onBeforeRouteLeave 这两个钩子,可以直接在 setup 中使用,而不再依赖组件选项(Options API)。
-
Vue 2 中,路由守卫在组件选项中定义。
export default {beforeRouteEnter(to, from, next) {// 在进入组件前调用next();},beforeRouteUpdate(to, from, next) {// 路由更新时调用next();},beforeRouteLeave(to, from, next) {// 离开组件时调用next();}};
Vue 3 中,可以在 setup 中直接使用 onBeforeRouteUpdate 和 onBeforeRouteLeave。
import { onBeforeRouteUpdate, onBeforeRouteLeave } from 'vue-router';export default {setup() {onBeforeRouteLeave((to, from) => {// 路由离开时触发的守卫});onBeforeRouteUpdate((to, from) => {// 路由更新时触发的守卫});}};
4. 组合式 API 的支持
Vue 3 使用了 useRouter 和 useRoute 这两个 Composition API,能够在 setup 中方便地访问路由实例和路由信息。这在 Vue 2 中是无法做到的,因为 Vue 2 的 vue-router 与 Options API 深度耦合。
import { useRouter, useRoute } from 'vue-router';export default {setup() {const router = useRouter();const route = useRoute();const goToHome = () => {router.push({ name: 'Home' });};return { goToHome, route };}};
5. 路由模式的选择
-
Vue 2 中,使用
mode参数来决定使用history还是hash模式。
const router = new VueRouter({mode: 'history', // 或者 'hash'routes});
Vue 3 中,使用 createWebHistory() 或 createWebHashHistory() 明确区分路由模式。
const router = createRouter({history: createWebHistory(), // 或者 createWebHashHistory()routes});
6. 其他差异
-
更好的 TypeScript 支持:Vue 3 和
vue-router@4对 TypeScript 进行了优化,提供了完整的类型推断和类型检查。 -
过渡效果改进:Vue 3 的
<router-view>支持新的v-slot用法来控制过渡效果。
二、Vue Router 的原理解析
1. 路由的核心原理
Vue Router 的核心原理就是通过 Hash 模式 或 History 模式 来监听 URL 的变化,从而实现视图组件的动态切换。
-
Hash 模式:通过监听
window.onhashchange事件来感知 URL 中#后面内容的变化。 -
History 模式:基于
window.history.pushState和window.history.replaceStateAPI 来修改 URL,并通过popstate事件监听 URL 的变化。
2. 路由匹配机制
Vue Router 的路由匹配基于路由表 (routes) 进行匹配。它使用了 path-to-regexp 库将 path 转换成正则表达式,并与当前 URL 进行比对,从而找到合适的路由。
-
每个路由规则(
RouteRecord)都包含path、component等信息。 -
在匹配过程中,会将路由表中的每一个
RouteRecord进行遍历,并基于路径解析进行比对。 -
一旦找到匹配的路由规则,就会渲染对应的组件。
3. 导航守卫执行顺序
Vue Router 提供了三种导航守卫:全局守卫、路由独享守卫和组件内守卫。它们的执行顺序如下:
-
全局前置守卫 (
beforeEach) -
路由独享守卫 (
beforeEnter) -
组件内守卫 (
beforeRouteEnter) -
全局解析守卫 (
beforeResolve) -
全局后置守卫 (
afterEach)
4. 路由切换过程
-
路由解析:在
router.push或者 URL 变化时,路由会首先匹配路由表中符合条件的路由规则。 -
执行导航守卫:依次执行全局、路由独享和组件内的导航守卫。
-
更新视图:在守卫全部通过后,更新组件树,重新渲染
router-view视图。
三、总结
Vue 3 的 vue-router@4 相较于 Vue 2 更加现代化和灵活,并且对 TypeScript 进行了更好的支持。与此同时,Vue 3 的路由实现基于 Composition API,使其能够更好地与 Vue 3 的设计理念相契合,提升了开发体验和可维护性。
