一、Vue2和Vue3路由的区别
1.1创建路由实例方式的不同
Vue2中,通过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');
Vue3中,通过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');
1.2动态路由的添加方式
Vue2中使用addRoutes()来动态添加多个路由,这个方法在Vue3中被移除。
router.addRoutes([ { path: '/about', component: About }]);
Vue3中使用addRoute()来动态添加单个路由,且可以指定父级路由进行嵌套路由的动态添加。
router.addRoute({ path: '/about', component: About });
router.addRoute('parent', { path: 'child', component: Child });
1.3路由守卫的变化
Vue 3 在组合式 API (setup
) 中新增了 onBeforeRouteUpdate
和 onBeforeRouteLeave
这两个钩子,可以直接在 setup
中使用,而不再依赖组件选项(Options API)。
Vue2中,路由守卫组件选项中定义
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) => {
// 路由更新时触发的守卫
});
}};
1.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 };
}};
1.5路由模式的选择
Vue2中,使用 mode
参数来决定使用 history
还是 hash
模式。
const router = new VueRouter({
mode: 'history', // 或者 'hash'
routes});
Vue3中,使用 createWebHistory()
或 createWebHashHistory()
明确区分路由模式。
const router = createRouter({
history: createWebHistory(), // 或者 createWebHashHistory()
routes});
1.6其他
- 更好的TypeScript支持:Vue3 和
vue-router@4
对 TypeScript 进行了优化,提供了完整的类型推断和类型检查。 - 过渡效果改进:Vue 3 的
<router-view>
支持新的v-slot
用法来控制过渡效果。
二、Vue Router 的原理解析
2.1.路由的核心原理
Vue Router的核心原理就是通过Hash模式或History模式来监听URL的变化,从而实现视图组件的动态切换。
- Hash模式:通过监听
window.onhashchange
事件来感知 URL 中#
后面内容的变化。 - History模式:基于
window.history.pushState
和window.history.replaceState
API 来修改 URL,并通过popstate
事件监听 URL 的变化。
2.2.路由匹配机制
Vue Router 的路由匹配基于路由表 (routes
) 进行匹配。它使用了 path-to-regexp
库将 path
转换成正则表达式,并与当前 URL 进行比对,从而找到合适的路由。
- 每个路由规则(
RouteRecord
)都包含path
、component
等信息。 - 在匹配过程中,会将路由表中的每一个
RouteRecord
进行遍历,并基于路径解析进行比对。 - 一旦找到匹配的路由规则,就会渲染对应的组件。
2.3.导航守卫执行顺序
Vue Router 提供了三种导航守卫:全局守卫、路由独享守卫和组件内守卫。它们的执行顺序如下:全局前置守卫 (beforeEach
)、路由独享守卫 (beforeEnter
)、组件内守卫 (beforeRouteEnter
)、全局解析守卫 (beforeResolve
)、全局后置守卫 (afterEach
)
2.4.路由切换过程
- 路由解析:在
router.push
或者 URL 变化时,路由会首先匹配路由表中符合条件的路由规则。 - 执行导航守卫:依次执行全局、路由独享和组件内的导航守卫。
- 更新视图:在守卫全部通过后,更新组件树,重新渲染
router-view
视图。