Vue Router 3 升级 4:写法、坑点、兼容一次讲透

Vue 项目升级时,Router 往往被忽略。结果上线后刷新 404、动态路由失效、守卫不生效......今天我们把 Vue Router 3 → 4 的变化拆成三个部分:新写法、常见坑、兼容技巧,用最直白的方式让你迅速搞懂。

🧭 新旧对比:核心变化一眼看懂

点位 Vue Router 3 Vue Router 4
创建方式 new Router({ ... }) createRouter({ ... })
历史模式 mode: 'history' history: createWebHistory()
动态添加路由 router.addRoutes([...]) router.addRoute('parent', route)
路由守卫 beforeEach((to, from, next) => {}) 参数顺序相同,但必须显式返回值或调用 next()
命名视图参数 props: { default: true } 写法一致,但 props 支持函数返回
TypeScript 支持 需要额外类型声明 内置完整类型

🛠️ 创建路由的写法

Vue Router 3

js 复制代码
import Vue from 'vue';
import Router from 'vue-router';
import Home from '@/views/Home.vue';

Vue.use(Router);

export default new Router({
  mode: 'history',
  routes: [
    { path: '/', name: 'Home', component: Home },
  ],
});

Vue Router 4(配合 Vue3)

js 复制代码
import { createRouter, createWebHistory } from 'vue-router';
import Home from '@/views/Home.vue';

const routes = [
  { path: '/', name: 'Home', component: Home },
];

const router = createRouter({
  history: createWebHistory(),
  routes,
});

export default router;
  • 不需要 Vue.use。
  • history 改成函数。
  • 默认导入 createRouter、createWebHashHistory、createMemoryHistory。

🚦 动态路由怎么改?

Vue Router 3

js 复制代码
router.addRoutes([
  {
    path: '/admin',
    component: AdminLayout,
    children: [
      { path: 'user', component: UserList },
    ],
  },
]);

Vue Router 4

js 复制代码
router.addRoute({
  path: '/admin',
  component: AdminLayout,
});

router.addRoute('admin', {
  path: 'user',
  component: UserList,
});
  • 先添加父路由,再给父路由添加子路由。
  • 返回 removeRoute 方法可以卸载路由(做权限控制非常方便)。

🧪 路由守卫写法

Vue Router 4 的守卫新增了返回值写法:

js 复制代码
router.beforeEach((to, from) => {
  const isLogin = Boolean(localStorage.getItem('token'));
  if (!isLogin && to.meta.requiresAuth) {
    return { name: 'Login', query: { redirect: to.fullPath } };
  }
  // 返回 undefined 或 true 表示放行
});
  • 不再强制调用 next()。
  • 也可以返回 false 来取消导航。

🌍 刷新 404 怎么办?

  • Vue Router 3:在生产环境加 try_files $uri $uri/ /index.html;
  • Vue Router 4:依旧如此,区别只是如果你用了 createWebHistory('/app/'),Nginx 也要配置子目录。

🔁 keep-alive 配合

  • Vue Router 3 中 keep-alive 通过 include、exclude 管控。

  • Vue Router 4 配合 <RouterView v-slot="{ Component }">,可以自定义渲染:

    vue 复制代码
    <RouterView v-slot="{ Component }">
      <KeepAlive include="UserList,UserDetail">
        <component :is="Component" />
      </KeepAlive>
    </RouterView>
  • 记得组件要有 name。

🧱 兼容 Vue2 项目:用 vue-router@4 + vue-demi?

  • Vue Router 4 专为 Vue3 设计,不兼容 Vue2。
  • 如果你还在 Vue2,可先升级到 vue-router@3.6,等待整体迁移完成后再上 4。
  • Vue2 项目想体验组合式写法,可以用 @vue/composition-api 插件,但 Router 要保持 3.x。

🧯 常见报错合集

报错 原因 解决
createRouter 未定义 仍在用 Vue Router 3 代码 确认安装 vue-router@4 并更新导入
刷新子路由 404 服务器没配置回退 nginx try_files 或 Vite historyApiFallback
动态路由不生效 忘记先添加父路由 先 addRoute(parent) 再加子路由
Navigation aborted 守卫返回 false 或抛异常 检查守卫返回值

📦 搭配 TypeScript 更顺手

ts 复制代码
import { RouteRecordRaw } from 'vue-router';

const routes: RouteRecordRaw[] = [
  {
    path: '/user/:id',
    name: 'UserDetail',
    component: () => import('@/views/UserDetail.vue'),
    props: (route) => ({ id: Number(route.params.id) }),
  },
];
  • RouteRecordRaw 声明类型。
  • props 支持函数返回,类型安全。

✅ 总结行动清单

  1. 改写 createRouter + createWebHistory。
  2. 动态路由全部用 addRoute。
  3. 路由守卫返回值改成 return,不再使用 next()。
  4. 部署时检查服务器的历史模式配置。
相关推荐
修炼的dance4 分钟前
录屏关键帧间隔多少合适?六档实测,2秒到10秒小了75.6%
前端
Lank_M10 分钟前
关键帧从1秒拉到10秒,录屏小87.3%,摄像头小10.8%
前端
补码缩写12 分钟前
用 ffprobe 拆录屏,八成字节在 29 个关键帧上
前端
百思不得小李14 分钟前
一个复杂的动态表单是如何实现的
前端·设计模式
陈随易28 分钟前
Cmder 停更 17 个月,2.0 支持 Windows Terminal
前端·后端·程序员
清晨Coding32 分钟前
删了 Cookie 还能自动登录?Google系网站登录态自动恢复的原理分析
javascript
风骏时光牛马39 分钟前
前沿视界
前端
kyriewen44 分钟前
我扫了 814 个依赖,97 个还敢要 Node 10
前端·javascript·程序员
陈随易1 小时前
3000 万人在用的翻译插件,重写一遍就是一门生意
前端·后端·程序员
IT_陈寒1 小时前
Vue的这个响应式陷阱,差点让我加班到天亮
前端·人工智能·后端