Code前端首页关于Code前端联系我们

Vue 2.7 该用哪个版本的 Vue Router?配置、实战和升级全解答

terry 6小时前 阅读数 9 #Vue
文章标签 7;Vue Router

Vue 2.7 作为 Vue 2 系列的“最终版本”,既保留了 2.x 的生态兼容性,又加入了 Composition API 等 Vue 3 特性,很多还没升级到 Vue 3 的团队会选择基于 2.7 做技术迭代,但路由作为单页应用的核心,Vue 2.7 该搭配哪个版本的 Vue Router?配置时要注意什么?和 Vue 3 版本有啥区别?这篇文章用问答形式把这些关键问题讲透。

Vue 2.7 适配的 Vue Router 版本是哪个?

Vue Router 分两大版本阵营:x 系列适配 Vue 2,4.x 系列只支持 Vue 3,Vue 2.7 必须用 Vue Router 3.x(3.6.5 是较新的稳定版)。

安装时要注意版本匹配,命令行执行 npm install vue-router@3(加 @3 指定 3.x 大版本,避免装到 4.x),装完后看 package.json,依赖里会显示 "vue-router": "^3.6.0" 这类版本号,代表成功锁定 3.x 系列。

为什么不能用 4.x?因为 Vue Router 4.x 底层依赖 Vue 3 的响应式系统和生命周期,和 Vue 2 的架构不兼容,4.x 里的 createRoutercreateWebHistory 这些 API,在 Vue 2 环境里根本跑不起来,会直接报错。

怎么给 Vue 2.7 项目配置 Vue Router 3.x?

配置分「安装→建路由文件→注入 Vue 实例→页面使用」四个步骤,下面用一个简单的多页路由示例拆解:

步骤1:安装依赖

打开终端,进入项目根目录,执行:
npm install vue-router@3 --save
如果是 yarn 则用 yarn add vue-router@3

步骤2:创建路由配置文件

src 目录下新建 router/index.js,写入基础配置:

import Vue from 'vue'  
import Router from 'vue-router'  
// 引入页面组件(可以用懒加载,后面讲)  
import Home from '@/views/Home.vue'  
import About from '@/views/About.vue'  
// 全局注册 Vue Router 插件  
Vue.use(Router)  
export default new Router({  
  // 路由模式:hash(默认,带 #)或 history(无 #,需后端配合)  
  mode: 'history',   
  routes: [  
    {  
      path: '/',  
      name: 'Home',  
      component: Home  
    },  
    {  
      path: '/about',  
      name: 'About',  
      component: About  
    }  
  ]  
})  

步骤3:注入到 Vue 实例

打开 src/main.js,把路由实例挂到 Vue 根实例上:

import Vue from 'vue'  
import App from './App.vue'  
import router from './router' // 引入刚才的路由配置  
new Vue({  
  router, // 注入路由  
  render: h => h(App)  
}).$mount('#app')  

步骤4:在页面中使用路由

App.vue 这类布局组件里,用 <router-view> 显示匹配的页面,用 <router-link> 做跳转:

<template>  
  <div id="app">  
    <router-link to="/">首页</router-link>  
    <router-link to="/about">关于我们</router-link>  
    <router-view></router-view> <!-- 页面内容渲染在这里 -->  
  </div>  
</template>  

配置完后,启动项目就能通过 和 /about 切换页面了,如果用 history 模式,要注意后端得配置首页重定向(Nginx 里加 try_files $uri $uri/ /index.html;),否则刷新页面会 404。

Vue Router 3.x 在 Vue 2.7 里和 Vue 3 版本有啥核心区别?

很多同学升级时会疑惑“都是 Vue Router,3.x 和 4.x 咋差这么多?”,核心区别集中在API 设计、框架耦合度、组合式 API 支持这三点:

路由实例的创建与挂载

Vue Router 3.x 是通过插件机制工作的:先 Vue.use(Router) 注册插件,再 new Router({...}) 创建实例,而 4.x 是函数式创建,用 createRouter 配合 createWebHistory 等方法,然后通过 app.use(router) 挂载到 Vue 3 的 App 实例上。

举个对比:

// Vue 2.7 + Router 3.x  
Vue.use(Router)  
export default new Router({ routes: [...] })  
// Vue 3 + Router 4.x  
const router = createRouter({  
  history: createWebHistory(),  
  routes: [...]  
})  
app.use(router)  

组合式 API 的支持度

Vue 2.7 能写 setup 语法,但 Vue Router 3.x 没有专门的组合式 API 工具(4.x 的 useRouteruseRoute),在 2.7 的 setup 里,要获取路由实例得用 getCurrentInstance 间接拿:

import { getCurrentInstance } from 'vue'  
export default {  
  setup() {  
    const { ctx } = getCurrentInstance()  
    const router = ctx.$router // 获取路由实例  
    const route = ctx.$route // 获取当前路由信息  
    return { router, route }  
  }  
}  

而 Vue 3 + Router 4.x 可以直接用:

import { useRouter, useRoute } from 'vue-router'  
const router = useRouter()  
const route = useRoute()  

路由模式的实现

Router 3.x 的 history 模式依赖第三方库(如 history 包),早期版本甚至需要手动引入;而 4.x 把路由模式(history/hash)的实现内置到核心,通过 createWebHistorycreateWebHashHistory 这些函数直接配置,更简洁。

类型定义与 TS 支持

Router 3.x 的 TypeScript 类型需要额外装 @types/vue-router,且类型定义相对“松散”;4.x 则把类型直接内置在包中,和 Vue 3 的响应式类型更贴合,TS 报错更精准。

简单说,3.x 是“Vue 2 时代的路由方案”,4.x 是“为 Vue 3 重构的现代化路由”,两者设计理念和实现方式差异很大,升级时不能直接替换版本号,得整体调整代码。

用 Vue 2.7 + Vue Router 3.x 做单页应用,实战场景怎么设计路由?

实际项目里,路由要处理权限控制、页面嵌套、动态参数、性能优化这些需求,下面分场景讲落地方法:

场景1:权限控制(登录拦截)

很多页面需要登录后才能访问(比如订单页),用全局路由守卫实现:

// router/index.js  
router.beforeEach((to, from, next) => {  
  const isLogin = localStorage.getItem('token') // 假设用 token 判断登录  
  if (to.meta.requiresAuth) { // 路由元信息标记是否需要登录  
    if (isLogin) {  
      next() // 已登录,放行  
    } else {  
      next('/login') // 未登录,跳登录页  
    }  
  } else {  
    next() // 不需要登录,直接放行  
  }  
})  
// 路由规则里加 meta  
routes: [  
  {  
    path: '/order',  
    name: 'Order',  
    component: () => import('@/views/Order.vue'), // 懒加载  
    meta: { requiresAuth: true } // 需要登录  
  }  
]  

这样访问 /order 时,会先触发 beforeEach 检查登录状态,没登录就踢去登录页。

场景2:嵌套路由(后台管理系统常用)

比如后台有个 Layout 组件,包含侧边栏和顶栏,子页面(如用户列表、商品列表)要嵌套在 Layout 里,用 children 配置:

const router = new Router({  
  routes: [  
    {  
      path: '/admin',  
      component: Layout, // 父组件  
      children: [  
        {  
          path: 'users', // 子路由,访问 /admin/users  
          component: UserList  
        },  
        {  
          path: 'goods',  
          component: GoodsList  
        }  
      ]  
    }  
  ]  
})  

然后在 Layout.vue 里加 <router-view> 渲染子页面:

<template>  
  <div class="layout">  
    <aside>侧边栏</aside>  
    <main><router-view></router-view></main> <!-- 子页面渲染在这里 -->  
  </div>  
</template>  

场景3:动态路由(商品详情、用户个人页)

比如商品详情页,URL 是 /product/123123 是商品 ID,配置动态路由并获取参数:

routes: [  
  {  
    path: '/product/:id', // :id 是动态参数  
    component: ProductDetail,  
    name: 'ProductDetail'  
  }  
]  

ProductDetail.vue 里,通过 this.$route.params.id 获取 ID:

export default {  
  mounted() {  
    const productId = this.$route.params.id  
    this.fetchProductDetail(productId) // 调接口拿详情  
  }  
}  

场景4:路由懒加载(优化首屏速度)

如果所有页面都打包到一个 JS 文件里,首屏加载会很慢,用动态 import 实现路由懒加载,让页面组件按需加载:

routes: [  
  {  
    path: '/about',  
    component: () => import('@/views/About.vue') // 访问 /about 时才加载这个组件  
  }  
]  

Webpack 会把这个组件单独打包成一个 chunk,首屏只加载必要的代码,等用户点进 About 页面时再加载对应的 JS,减少首屏压力。

从 Vue 2 老项目升级到 2.7,Vue Router 要注意哪些坑?

很多团队是从 Vue 2.6 甚至更早版本升级到 2.7,升级时路由部分容易踩这些坑:

坑1:Vue Router 版本没锁对,装成 4.x

升级时如果执行 npm install vue-router 没加 @3,npm 会默认装最新的 4.x,直接导致项目报错(因为 4.x 不兼容 Vue 2),解决方法:卸载现有版本,重新装 3.x
npm uninstall vue-router && npm install vue-router@3 --save

坑2:路由配置里的废弃 API

Vue Router 3.x 后期版本(3.5+)废弃了一些老写法,component: resolve => require(['@/views/About.vue'], resolve) 这种回调式懒加载(Webpack 老写法),现在推荐用 () => import(...),如果项目里还有这类写法,升级后可能报语法错误,得批量替换成动态 import。

坑3:Composition API 里拿不到 $router/$route

Vue 2.7 支持 setup 语法,但 setup 里没有 this,如果直接写 this.$router 会报错,要通过 getCurrentInstance 取上下文:

import { getCurrentInstance } from 'vue'  
export default {  
  setup() {  
    const { ctx } = getCurrentInstance()  
    const router = ctx.$router  
    // 注意:生产环境可能要判断 ctx 是否存在(SSR 场景)  
    return { router }  
  }  
}  

坑4:第三方路由插件不兼容

如果项目里用了 vue-router-tabsvue-router-cache 这类第三方路由插件,要检查它们是否支持 Vue Router 3.x 的最新版,比如某些插件只适配到 3.2.x,升级到 3.6.x 后可能出现路由切换异常,这时候要么升级插件版本,要么换替代方案。

坑5:history 模式的后端配置没同步升级

如果项目用 history 模式,升级前后端(Nginx、Apache)的重定向配置是适配旧版 Vue 的,升级后要确保所有 404 请求都重定向到 index.html,Nginx 配置:

location / {  
  try_files $uri $uri/ /index.html;  
}  

如果没配这个,刷新页面就会出现 404,得和后端同学同步配置。

Vue 2.7 + Vue Router 3.x 性能优化有哪些技巧?

单页应用用户体验差,很多时候是路由加载慢、组件重复渲染导致的,这几个技巧能有效优化:

技巧1:路由懒加载 + 分块打包

前面讲过用 () => import('@/views/Page.vue') 做懒加载,Webpack 会把每个页面打成单独的 JS 块,还能进一步用 webpackPrefetchwebpackPreload 让浏览器提前加载关键页面:

component: () => import(/* webpackPrefetch: true */ '@/views/Checkout.vue')  

这样浏览器会在空闲时预加载 Checkout 页面的代码,用户点结算时能更快打开。

技巧2:路由预加载(提前加载下一个页面)

比如用户 hover 导航栏的“订单”按钮时,提前加载订单页组件,用 router.beforeResolve 实现:

// 假设导航栏按钮的 hover 事件里触发预加载  
const preloadOrderPage = () => {  
  router.beforeResolve(to => {  
    if (to.name === 'Order') {  
      import('@/views/Order.vue') // 提前加载,不影响当前路由  
    }  
  })  
}  

这样用户真正点击“订单”时,组件已经加载好了,切换更丝滑。

技巧3:keep-alive 缓存路由组件

很多页面(比如表单页、列表页)切换后再切回来,重新渲染很耗时,用 <keep-alive> 缓存组件实例:

<template>  
  <div id="app">  
    <keep-alive>  
      <router-view v-if="$route.meta.keepAlive"></router-view>  
    </keep-alive>  
    <router-view v-if="!$route.meta.keepAlive"></router-view>  
  </div>  
</template>  

然后在路由规则里标记哪些页面要缓存:

routes: [  
  {  
    path: '/form',  
    component: FormPage,  
    meta: { keepAlive: true } // 缓存这个页面  
  }  
]  

这样 FormPage 组件切换后再回来,不会重新执行 createdmounted 等钩子,数据和状态都保留,性能提升明显。

技巧4:用异步组件 + Suspense(实验性)

Vue 2.7 支持实验性的 <Suspense> 组件,可以配合异步组件做加载态:

<template>  
  <Suspense>  
    <template #default><AsyncComponent /></template>  
    <template #fallback><div>加载中...</div></template>  
  </Suspense>  
</template>  
<script>  
export default {  
  components: {  
    AsyncComponent: () => import('@/components/AsyncComponent.vue')  
  }  
}  
</script>  

虽然 <Suspense> 在 2.7 是实验性特性,但能让路由切换时的加载态更友好,减少用户等待焦虑。

Vue 2.7 搭配 Vue Router 3.x 是“稳中求进”的技术选择——既享受 2.7 的 Composition API 等新特性,又能复用 Vue 2 成熟的路由生态,掌握版本匹配、配置流程、实战场景和升级坑点,就能在老项目迭代或新项目启动时,把

版权声明

本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

热门