用 Vite + Vue 3 快速搭建现代前端项目:从零到多页面路由实战
大家好,今天来分享一篇实战向的教程:基于 Vite 搭建 Vue 3 项目,并集成 Vue Router 实现多页面切换。在 2025 年底的今天,Vite 已经彻底取代了 Vue CLI 成为 Vue 生态的标配构建工具。它启动快、热更新丝滑、配置简洁,完美契合 Vue 3 的现代开发体验。
如果你还在用老旧的 Webpack 脚手架,那真的该升级了!这篇文章将手把手带你从项目初始化到路由配置,全程代码可复制,逻辑清晰。预计阅读完后,你能独立搭建一个规范的 Vue 3 + Vite 项目。
一、为什么选择 Vite + Vue 3?
先说说底层逻辑,为什么这对组合这么香?
-
Vite 的核心优势:传统工具如 Webpack 在开发时需要先打包整个项目,启动慢、热更新卡顿。Vite 不同,它利用浏览器原生 ES Modules(ESM)支持,按需加载模块。开发服务器启动时几乎不需要预打包,冷启动只需几百毫秒!
-
热模块替换(HMR)原理:当你修改文件,Vite 通过文件监听器(chokidar)检测变化,只更新受影响的模块,并 via WebSocket 推送给浏览器。浏览器只需替换局部模块,而非整页刷新。这就是为什么 Vite 的热更新能达到毫秒级,甚至大项目也丝滑如 butter。
-
Vue 3 的革新:更小的体积(减少 41%)、更快的运行时、Composition API + < script setup> 语法糖,让代码更简洁、可复用性更高。
总之,这套栈是当前最高效的现代前端工程化方案。
二、项目初始化:一步到位
推荐使用官方脚手架 npm init vite。
npm init vite
cd my-vue-app
npm install
npm run dev
交互过程中:
- 选择
vue模板(默认就是 Vue 3)。 - 其他选项根据需要(JSX、路由等现在不选,后续手动加)。
启动后访问 http://localhost:5173,看到欢迎页就成功了!
易错提醒:如果端口被占用,Vite 会自动切换端口,但你可以手动在 vite.config.js 配置 server.port。
三、项目结构剖析:标准模版长啥样?
一个典型的 Vite + Vue 3 项目结构如下:
关键文件解释:
-
index.html:入口 HTML,Vite 以它为根。注意
<script type="module" src="/src/main.js"></script>,这就是利用 ESM 的关键!浏览器直接导入模块,按需加载。 -
src/main.js(或 main.ts):应用入口,创建 Vue App 并挂载到
#app。 -
src/App.vue:根组件,通常放布局和路由占位。
-
src/assets:图片等资源。
-
src/components:公共组件。
-
public:静态资源,直接复制到 dist。
底层逻辑:Vite 在开发模式下不打包,而是让浏览器直接请求 ESM 模块。生产构建时才用 Rollup 打包,体积小、Tree-shaking 完美。
开发工具推荐:
- VSCode 插件:Volar(Vue 官方,取代 Vetur),提供智能提示、类型检查。
- Chrome 插件:Vue Devtools,调试神器。
四、集成 Vue Router:实现多页面切换
单页应用(SPA)的核心就是路由。Vue Router 4 是 Vue 3 的官方路由。
1. 安装
npm install router
2. 创建路由配置(src/router/index.js)
// router 模块 定义路由
import {
createRouter,//路由实例
createWebHashHistory//路由模式
} from 'vue-router';
import Home from '../views/Home.vue';
import About from '../views/About.vue';
const routes=[
{
path:'/',
name:'Home',
component:Home
},
{
path:'/about',
name:'About',
component:About
}
];
//实例化 负责前端路由
const router = createRouter({
//访问历史 hash 路由 #/about
history:createWebHashHistory(),
//路由配置数组
routes
})
export default router;
3. 创建视图页面(src/views/Home.vue & About.vue)
<!-- Home.vue -->
<template>
<div class="home">
<h1>欢迎来到 Home 页面!</h1>
<p>这里是首页内容。</p>
</div>
</template>
About.vue 同理,改成 About 内容。
4. 在 main.js 注册路由
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import './style.css'
createApp(App).use(router).mount('#app')
5. 在 App.vue 使用路由
<script setup>
// 无需额外导入,<script setup> 下直接可用
</script>
<template>
<header>
<nav>
<ul>
<li><router-link to="/">Home</router-link></li>
<li><router-link to="/about">About</router-link></li>
</ul>
</nav>
</header>
<main>
<router-view /> <!-- 这里渲染匹配的页面组件 -->
</main>
</template>
<style scoped>
nav ul { display: flex; list-style: none; gap: 20px; }
router-link { text-decoration: none; font-weight: bold; }
</style>
运行 npm run dev,点击导航,就能无缝切换页面了!
路由模式详解:Hash vs History
-
createWebHashHistory()(带 #):URL 如
/ '#/about。优点:无需服务器配置,兼容性好(静态托管如 GitHub Pages 直接可用)。缺点:URL 不美观,不利于 SEO。 -
createWebHistory()(推荐生产用):URL 如
/about。干净美观,支持 SEO。但需要服务器配置 fallback(所有路径指向 index.html),否则刷新 404。
易错提醒:
- 切换到 History 模式后,本地开发正常,但部署到 Nginx/Apache 时必须配置重写规则。
- 示例 Nginx 配置: location / { try_files uri/ /index.html; }
- 如果项目是纯静态部署,建议先用 Hash 模式,避免坑。
五、几个细节知识点
1、<script type="module" src="/src/main.js"></script>,这就是利用 ESM 的关键!浏览器直接导入模块,按需加载。
这是 Vite 极速开发的核心秘密!
-
导入的是什么模块? 浏览器直接把 /src/main.js 当作一个 ES Module(原生 JS 模块) 来导入。 main.js 里面有各种 import 语句,比如:
JavaScript
import { createApp } from 'vue' import App from './App.vue' import router from './router' import './style.css'所以,浏览器加载 main.js 后,会解析这些 import,继续去请求 'vue'、'./App.vue'、'./router/index.js' 等模块。
-
按什么“需”加载? → 按需加载(On-Demand Loading) 传统工具(如 Webpack + Vue CLI)在开发模式下,会先把所有代码打包成一个大 bundle.js,然后浏览器才加载这个大文件。项目一大,启动就卡几秒甚至十几秒。
Vite 完全不一样(开发模式下):
-
Vite 的 dev server 启动后,不预打包任何东西。
-
浏览器先加载 index.html → 执行
-
Vite server 收到请求 main.js 时,会实时转化代码(比如把 .vue 单文件组件转成 JS),然后返回。
-
main.js 执行时遇到 import,浏览器又会立刻去请求那些被导入的模块(Vite 帮忙预处理 .vue、CSS 等)。
-
只有当前路径依赖到的模块才会被加载,没用到的根本不请求!
-
这就是“按需加载”:浏览器像蜘蛛网一样,一层一层按实际依赖和路由需求去拉取模块,而不是一次性全拉下来。
左边传统方式要等打包完,Vite 直接边用边加载,启动快得飞起!
2、index.html 里的 #app 挂载点
这是单页应用(SPA)的精髓!很多人以为“多页面”就要多个 HTML 文件,其实完全不是。
-
只有一个挂载点:Vue 应用整个挂载在 #app 这个 div 上。
HTML
<div id="app"></div>main.js 里 createApp(App).mount('#app') 就是把根组件 App.vue 的内容渲染到这个 div 里。
-
其他“页面”内容挂载在哪儿? 它们根本不是独立的 HTML 页面,而是 Vue 组件,通过 Vue Router 的 动态插入到 App.vue 的模板里!
看你的 App.vue:
vue
<template> <header>导航...</header> <main> <router-view></router-view> <!-- 关键就在这里! --> </main> </template>- 是一个占位符(Outlet)。
- 当你访问 / 时,Vue Router 会把 Home.vue 组件渲染到这个 位置。
- 访问 /about 时,就把 About.vue 渲染到同一个位置。
- 整个过程:页面不刷新,只有 里面的内容被替换,导航栏、footer 等公共部分保持不动。
所以,整个应用永远只有一个 HTML(index.html),所有“页面切换”其实是组件的动态替换。URL 变了(hash 或 history 模式),但浏览器没重新加载整个页面。
3、拆解 routes 数组,彻底搞清楚它在干啥:
JavaScript
const routes = [
{
path: '/', // 1. URL 路径
name: 'Home', // 2. 路由名称(可选,但强烈推荐)
component: Home // 3. 当路径匹配时,要渲染的组件
},
{
path: '/about',
name: 'About',
component: About
}
];
每个字段的具体含义
-
path: '/' 或 path: '/about' (去哪)
- 这就是浏览器地址栏里的路径。
- 当用户在浏览器输入或点击链接访问 http://localhost:5173/ 时,会匹配第一个路由(path: '/')。
- 访问 http://localhost:5173/about 时,会匹配第二个路由。
- 如果用 Hash 模式,会是 #/ 和 #/about;用 History 模式就是干净的 / 和 /about。
简单说:path 决定了“用户访问什么地址时触发这个路由” 。
-
name: 'Home' 或 name: 'About'(叫啥)
- 给这个路由起一个名字,方便在代码里引用。
- 比如用 跳转,或者在 JS 里 router.push({ name: 'Home' })。
- 虽然不是必须的,但大项目里用 name 跳转比写死 path 更安全(路径改了也不用到处改)。
-
component: Home 或 component: About(看啥)
-
这里就是引用前面 import 进来的组件。
-
Home 和 About 是你在文件顶部通过下面代码导入的变量:
JavaScript
import Home from '../views/Home.vue'; import About from '../views/About.vue'; -
当路径匹配成功后,Vue Router 就会把这个组件渲染到 App.vue 里的 位置。
简单说:component 决定了“访问这个路径时,显示哪个页面内容” 。
-
用大白话总结整个过程
想象 Vue Router 是一个前台接待:
- 用户来了,说:“我要去首页!”(浏览器地址变成 /)
- 前台(Vue Router)一看 routes 配置表:哦,path: '/' 对应 component: Home
- 然后把 Home.vue 这个“房间”(组件)打开,放到 这个展示柜里让你看
- 用户又说:“我要去关于页面!”(地址变成 /about)
- 前台再查表:path: '/about' 对应 component: About
- 就把 About.vue 放进去展示
整个过程页面不刷新,只有展示柜里的内容换了。
六、总结与展望
通过这篇文章,我们从 Vite 的极速原理出发,完整搭建了一个带路由的 Vue 3 项目。核心是理解 ESM + HMR(热模块替换) 的现代逻辑,让开发体验飞起。