Vite 项目里咋装 Vue Router?
不少刚接触 Vite + Vue 技术栈的同学,都会疑惑「Vue Router 在 Vite 里咋用?」,毕竟 Vite 和传统 Vue CLI 搭建的项目结构、工具链不一样,路由配置、功能实现也得跟着调整,这篇文章就从安装到进阶,一步步把 Vue Router 在 Vite 项目里的玩法讲透,不管是基础路由、动态路由,还是和 Vite 特性结合的技巧,都给你说明白~
想在 Vite 项目里用 Vue Router,第一步得把依赖装上,打开终端,根据你用的包管理器选命令: - 用 npm 的话,输入 `npm install vue-router@4`(注意 Vue Router 4 对应 Vue 3,Vite 项目默认是 Vue 3 环境); - 用 yarn 就 `yarn add vue-router@4`; - pnpm 则是 `pnpm add vue-router@4`。装完后,得给项目搭路由的基础结构,一般在 src
文件夹下新建 router
目录,里面建 index.js
(也可以叫 router.js
),在这个文件里,要做这些事:
- 从
vue-router
里导入createRouter
、createWebHistory
(或createWebHashHistory
,后面讲区别); - 导入要配置的页面组件(
HomeView.vue
、AboutView.vue
); - 定义
routes
数组,每个对象对应一条路由规则; - 用
createRouter
生成路由实例,配置history
和routes
。
举个简单的配置例子:
// src/router/index.js import { createRouter, createWebHistory } from 'vue-router' import HomeView from '../views/HomeView.vue' import AboutView from '../views/AboutView.vue' const routes = [ { path: '/', name: 'home', component: HomeView }, { path: '/about', name: 'about', component: AboutView } ] const router = createRouter({ history: createWebHistory(), // 用 HTML5 History 模式 routes }) export default router
得把这个路由实例注入到 Vue 应用里,打开 src/main.js
,导入并使用:
// src/main.js import { createApp } from 'vue' import App from './App.vue' import router from './router' // 导入刚才写的路由配置 const app = createApp(App) app.use(router) // 挂载路由 app.mount('#app')
这样,Vue Router 就在 Vite 项目里初步跑起来了~
基础路由配置要注意啥?
基础路由配置核心是 routes
数组和 history
模式的选择,这俩地方容易踩坑。
history
模式咋选?
Vue Router 提供了两种常见的历史模式:
createWebHistory
:对应 HTML5 History 模式,URL 长得干净(/about
),但部署到服务器时得配置 fallback(否则刷新页面会 404);createWebHashHistory
:对应哈希模式,URL 带 (/#/about
),兼容性好,部署时不用额外配置服务器,但 URL 里多了个 可能影响美观。
在 Vite 项目里,如果是开发阶段,两种模式都能直接用;但生产部署时,用 createWebHistory
得让服务器支持「所有请求都转发到 index.html」,比如用 Nginx 部署,得加这么一段配置:
location / { try_files $uri $uri/ /index.html; }
要是项目部署在子路径下(https://xxx.com/my-app/
),还得给 createWebHistory
传参数设置 base
:
history: createWebHistory('/my-app/'),
路由组件咋组织?
路由里的 component
字段,既可以直接导入组件(像前面例子那样),也能配合「动态导入」做懒加载(后面专门讲),组件的路径别写错!Vite 里默认支持 别名(对应 src
目录),但得先在 vite.config.js
里配置:
// vite.config.js import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import path from 'path' export default defineConfig({ plugins: [vue()], resolve: { alias: { '@': path.resolve(__dirname, 'src') // 配置 @ 指向 src } } })
这样在路由里导入组件就能写 import HomeView from '@/views/HomeView.vue'
,更简洁~
动态路由和参数咋玩?
很多场景需要「动态路由」,比如用户详情页 /user/123
,这里的 123
是用户 ID,得从路由里拿到参数。
定义动态路由
在 routes
里用 :参数名
定义动态段,
{ path: '/user/:id', name: 'user', component: () => import('@/views/UserView.vue') // 这里先用懒加载演示 }
组件内获取参数
在 Vue 3 的组合式 API 里,得用 useRoute
钩子来拿路由参数,比如在 UserView.vue
里:
<template> <div>用户 ID:{{ route.params.id }}</div> </template> <script setup> import { useRoute } from 'vue-router' const route = useRoute() // 拿到当前路由对象 console.log(route.params.id) // 就能拿到动态参数 id </script>
如果是用选项式 API(export default { ... }
),则是通过 this.$route.params.id
获取~
路由传参的两种方式
除了 URL 里的动态段(params
),还能通过 query
传参(类似 URL 里的 ?name=xxx
),比如跳转时:
// 用 router.push 跳转,两种传参方式 router.push({ name: 'user', params: { id: 123 } }) // params 传参,URL 是 /user/123 router.push({ path: '/user/123', query: { tab: 'info' } }) // query 传参,URL 是 /user/123?tab=info
区别是:params
传的参数不会显示在 URL 上,刷新页面后会丢失;query
传的参数会拼在 URL 里,刷新还在,根据场景选就行~
嵌套路由咋实现?
做后台管理系统时,经常需要「嵌套路由」,比如顶部导航是 /dashboard
,下面还有 /dashboard/home
、/dashboard/settings
这些子页面。
配置嵌套路由
在 routes
里给父路由加 children
数组,子路由的 path
不用写斜杠开头(除非要强制从根路径开始),举个例子:
{ path: '/dashboard', name: 'dashboard', component: () => import('@/views/DashboardLayout.vue'), // 父布局组件 children: [ { path: '', // 空路径表示默认子路由,访问 /dashboard 时显示这个 name: 'dashboard-home', component: () => import('@/views/DashboardHome.vue') }, { path: 'settings', name: 'dashboard-settings', component: () => import('@/views/DashboardSettings.vue') } ] }
父组件里放 <router - view>
父组件(DashboardLayout.vue
)得用 <router-view>
来显示子路由对应的组件,结构大概这样:
<template> <div class="dashboard-layout"> <aside>侧边栏</aside> <main> <router-view></router-view> <!-- 子路由组件会渲染到这里 --> </main> </div> </template>
这样,访问 /dashboard
时,显示 DashboardHome.vue
;访问 /dashboard/settings
时,显示 DashboardSettings.vue
,同时父组件的布局(侧边栏)会一直保留~
路由守卫咋用起来?
路由守卫能控制「哪些页面能访问、访问前要做啥」,比如权限验证、加载动画,Vue Router 4 里守卫分三类:全局守卫、路由独享守卫、组件内守卫。
全局守卫(控制所有路由)
最常用的是 router.beforeEach
(导航前触发)和 router.afterEach
(导航后触发),比如做登录验证:
// src/router/index.js import { createRouter, createWebHistory } from 'vue-router' import store from '@/store' // 假设用 Pinia 或 Vuex 存用户状态 const router = createRouter({ ... }) router.beforeEach((to, from, next) => { // 如果要去的页面需要登录,且用户没登录,就跳转到登录页 if (to.meta.requiresAuth && !store.state.user.isLogin) { next({ name: 'login' }) } else { next() // 允许导航 } }) export default router
这里的 to.meta.requiresAuth
是给路由加「元信息」,比如在路由配置里:
{ path: '/profile', name: 'profile', component: () => import('@/views/ProfileView.vue'), meta: { requiresAuth: true } // 标记该页面需要登录 }
路由独享守卫(只控制单个路由)
在路由配置里用 beforeEnter
,比如某个页面只能特定角色访问:
{ path: '/admin', name: 'admin', component: () => import('@/views/AdminView.vue'), beforeEnter: (to, from, next) => { if (store.state.user.role === 'admin') { next() } else { next({ name: 'home' }) } } }
组件内守卫(组件级控制)
在组合式 API 里,用 onBeforeRouteEnter
、onBeforeRouteUpdate
、onBeforeRouteLeave
这几个钩子,比如离开页面时提示保存:
<template>...</template> <script setup> import { onBeforeRouteLeave } from 'vue-router' onBeforeRouteLeave((to, from, next) => { const isSaved = ... // 判断表单是否保存 if (isSaved || window.confirm('内容没保存,确定离开?')) { next() } else { next(false) // 取消导航 } }) </script>
这些守卫能灵活控制路由导航的时机,适配各种业务场景~
路由懒加载咋搞?
路由懒加载能让页面「按需加载」,减少首屏打包体积,提升加载速度,在 Vite 里实现很简单,用 ES6 的 import()
语法就行。
基础用法
把路由配置里的 component
改成动态导入的函数:
{ path: '/about', name: 'about', component: () => import('@/views/AboutView.vue') // 这样 AboutView 就会懒加载 }
打包后,每个懒加载的组件会单独生成一个 chunk,访问对应路由时才会加载这个 chunk~
给 chunk 加名字(可选)
虽然 Vite 用 Rollup 打包,但也支持「魔法注释」给 chunk 命名,方便调试:
component: () => import(/* webpackChunkName: "about" */ '@/views/AboutView.vue')
这样打包后,这个 chunk 的名字会包含 about
,找问题时更直观~
和 Vite 特性结合有啥技巧?
Vite 本身有很多特性(比如别名、环境变量、HMR),和 Vue Router 结合起来能更顺手。
用 Vite 别名简化路径
前面提过,配置 vite.config.js
里的 resolve.alias
后,路由里导入组件可以用 @/xxx
,不用写相对路径。
import HomeView from '@/views/HomeView.vue' // 比 '../../views/HomeView.vue' 清爽多了
结合环境变量配置 base
如果项目在开发和生产环境的部署路径不一样,可以用 Vite 的环境变量动态设置 history
的 base
,比如在 .env.development
里:
VITE_APP_BASE = '/'
在 .env.production
里:
VITE_APP_BASE = '/my-app/'
然后在路由配置里读取:
import.meta.env.VITE_APP_BASE // 拿到环境变量 history: createWebHistory(import.meta.env.VITE_APP_BASE),
利用 Vite 的 HMR 提升开发体验
Vite 对 Vue 组件的热更新(HMR)支持很好,路由配置文件(src/router/index.js
)修改后,页面会自动刷新,不用手动重启服务,甚至路由里的懒加载组件修改后,也能快速热更新,开发时更流畅~
看完这些,你应该对「Vue Router 在 Vite 里咋用」有清晰思路了吧?从安装、基础配置到动态路由、嵌套路由,再到守卫和懒加载,还有和 Vite 特性的结合,每个环节都有对应的玩法和注意点,实际项目里,得根据需求选合适的配置(比如历史模式、传参方式),再结合 Vite 的优势优化开发和生产体验,要是你在实践中碰到「路由跳转白屏」「参数拿不到」这类问题,先检查路径配置、组件导入、守卫逻辑这些点,一般就能找到原因~
版权声明
本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。