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

Vite 项目里咋装 Vue Router?

terry 2小时前 阅读数 4 #Vue
文章标签 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),在这个文件里,要做这些事:

  1. vue-router 里导入 createRoutercreateWebHistory(或 createWebHashHistory,后面讲区别);
  2. 导入要配置的页面组件(HomeView.vueAboutView.vue);
  3. 定义 routes 数组,每个对象对应一条路由规则;
  4. createRouter 生成路由实例,配置 historyroutes

举个简单的配置例子:

// 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 里,用 onBeforeRouteEnteronBeforeRouteUpdateonBeforeRouteLeave 这几个钩子,比如离开页面时提示保存:

<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 的环境变量动态设置 historybase,比如在 .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前端网发表,如需转载,请注明页面地址。

发表评论:

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

热门