核心理念与设计哲学的根本转变
Vue Router 3.x 和 4.x 的区别,远不止是 API 的变更,更是响应式系统、组件化思想和开发范式的全面进化。
-
Vue Router 3.x (Options API 时代):
- 中心化管理:路由逻辑(守卫、解析)主要在
router
实例和组件的options
(如beforeRouteEnter
)中定义。 - 隐式依赖:组件通过
this.$route
和this.$router
隐式地访问路由状态和方法。这使得组件与路由系统耦合,难以在非组件环境中复用逻辑。 - 响应式局限:依赖 Vue 2 的
Object.defineProperty
响应式系统,对路由参数变化的监听不够灵活(常需watch
$route
对象)。 - 类型支持弱:TypeScript 支持有限,类型推断困难。
- 中心化管理:路由逻辑(守卫、解析)主要在
-
Vue Router 4.x (Composition API 时代):
- 去中心化与组合式:鼓励将路由相关的逻辑(如根据参数获取数据、权限检查)封装成可复用的 Composition Functions (如
useUserById
,useAuthGuard
)。这些函数可以在任何setup
中使用,甚至在非组件的 JS/TS 文件中。 - 显式依赖:通过
useRoute()
和useRouter()
显式地引入所需的路由状态和方法。这使得依赖关系清晰,逻辑更易于测试和复用。 - 深度响应式集成:基于 Vue 3 的
Proxy
响应式系统,useRoute()
返回的route
是一个深度响应式的ref
。你可以直接watch
其.value
或解构出的属性,响应式更新更精细、更高效。 - 一流的 TypeScript 支持:从路由记录 (
RouteRecordRaw
) 到useRoute
的返回值,都提供了强大的类型定义和推断能力。
- 去中心化与组合式:鼓励将路由相关的逻辑(如根据参数获取数据、权限检查)封装成可复用的 Composition Functions (如
详细 API 变化与深入解析
1. 路由器实例创建 (createRouter
vs new VueRouter
)
-
Vue Router 3.x:
import Vue from 'vue' import VueRouter from 'vue-router' // 1. 安装插件 (全局操作) Vue.use(VueRouter) // 2. 创建实例 (构造函数) const router = new VueRouter({ mode: 'history', // 字符串标识 base: process.env.BASE_URL, // 基础路径 routes: [...], // 其他选项 }) export default router
Vue.use()
: 这是一个全局副作用,修改了Vue
构造函数本身,为所有 Vue 实例注入$router
和$route
。这在现代模块化开发中不够“纯净”。mode
选项: 使用字符串 ('history'
,'hash'
) 来指定模式。
-
Vue Router 4.x:
import { createApp } from 'vue' import { createRouter, createWebHistory, createWebHashHistory } from 'vue-router' import App from './App.vue' // 1. 创建路由器实例 (工厂函数) const router = createRouter({ // 2. 显式创建 history 实例 (函数式、模块化) history: createWebHistory(), // 或 createWebHashHistory('/base/') routes: [...], // 3. 其他选项 (部分被移除或重构) }) // 4. 创建应用实例 const app = createApp(App) // 5. 安装插件到应用实例 (非全局) app.use(router) // 6. 挂载 app.mount('#app')
createRouter()
: 工厂函数取代了构造函数。它返回一个路由器对象,不依赖于全局的Vue
实例。- 显式 History API:
createWebHistory(basePath?)
: 创建 HTML5 History 模式的 history 实例。basePath
是可选的根路径。createWebHashHistory(hashPrefix?)
: 创建 Hash 模式的 history 实例。hashPrefix
可以是#
,#!
等。createMemoryHistory(initialEntries?)
: 全新功能。创建一个不依赖浏览器 history 栈的内存 history。这对于测试、SSR (Server-Side Rendering) 或非浏览器环境(如 Electron, React Native)非常有用。
app.use(router)
: 插件安装在应用实例 (app
) 上,而不是全局的Vue
。这使得多个 Vue 应用可以共存且拥有独立的路由器,更符合现代应用架构。
2. 访问路由信息 (useRoute
vs this.$route
)
-
Vue Router 3.x:
export default { // 在 Options API 中 computed: { fullName() { // 通过 this.$route 访问 return this.$route.params.firstName + ' ' + this.$route.params.lastName } }, watch: { // 监听整个 $route 对象 '$route' (to, from) { // 当路由变化时,无论是 path, query, params this.fetchData(to.params.id) }, // 或者监听特定属性 (不够直观) '$route.params