前言
上回我们把 Vue 的响应式数据、ref、还有 Todos 任务清单都过了一遍,但说到底,那些都只在一个文件里打转——就像是在练习册上画画,还没真正盖房子。
今天咱们要搞点真家伙:一个拥有多页面、路由导航、组件化架构的现代前端应用。别看它小,麻雀虽小五脏俱全,Vue 3 项目开发的核心骨架一个不落:
- Vite 构建工具 —— 现代前端工程化的基石;
- Vue Router —— 前端路由,实现无刷新页面切换;
- 组件化架构 —— App.vue + views 目录结构;
- ESM 模块化 —— import/export 这变钱代 JS 规范。

一、项目结构:一个 Vue 项目的"五脏六腑"
复制代码all-vue/
├── public/
│ └── fa vicon.svg
├── src/
│ ├── router/
│ │ └── index.js # 路由配置
│ ├── views/
│ │ ├── Home.vue # 首页组件
│ │ └── About.vue # 关于页组件
│ ├── App.vue # 根组件
│ ├── main.js # 入口文件
│ └── style.css # 全局样式
├── index.html # HTML 入口
├── package.json
└── vite.config.js # Vite 配置
| 文件/目录 | 职责 | 类比 |
|---|---|---|
index.html | 整个应用的 HTML 入口 | 房子的地基 |
main.js | JS 入口,创建 Vue 应用实例 | 房子的总开关 |
App.vue | 根组件,包裹所有页面 | 房子的框架 |
router/index.js | 路由配置,决定 URL 对应哪个页面 | 房子的门牌号 |
views/*.vue | 具体的页面组件 | 房子的各个房间 |
style.css | 全局样式 | 房子的装修风格 |
vite.config.js | 构建工具配置 | 施工图纸 |
二、HTML 入口:一切的起点
复制代码
html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/fa vicon.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>all-vuetitle>
head>
<body>
<div id="app">div>
<script type="module" src="/src/main.js">script>
body>
html>
逐行解析:
复制代码<div id="app">div>
- 这就是 Vue 的挂载点——一个空的
div。Vue 会把整个 App.vue 组件渲染到这里,页面上其他内容都会被它接管。
复制代码<script type="module" src="/src/main.js">script>
type="module"表示使用 ESM(ES Modules)规范。为什么 Vite 要这么搞?因为 Vite 的开发服务器直接依赖浏览器的原生 ESM 能力,无需打包,所以 启动快得像闪电。
三、入口文件 main.js:Vue 应用的"总开关"
复制代码// main.js
import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
import router from './router';createApp(App)
.use(router) // 启用路由
.mount('#app') // 挂载到 #app
逐行拆解:
复制代码import { createApp } from 'vue'
- Vue 3 用
createApp创建应用实例,不再是 Vue 2 的new Vue()。这是一个工厂函数,返回一个应用实例对象。
复制代码import './style.css'
- 引入全局样式,Vite 会处理 CSS 的加载,这个样式对整个应用的所有组件生效。
复制代码import App from './App.vue'
- 引入根组件
App.vue。.vue文件是 Vue 的单文件组件(SFC),里面包含了模板、脚本和样式三件套。
复制代码import router from './router';
- 引入路由实例,路由是一个独立模块,负责 URL 和页面的映射。
复制代码createApp(App)
.use(router)
.mount('#app')
- 链式调用:
createApp(App)创建实例 →.use(router)安装路由插件 →.mount('#app')挂载到 DOM。.use()返回的还是同一个实例,所以可以继续调用。
四、路由配置:URL 和页面的"门牌号"
复制代码// router/index.js
import {
createRouter, // 创建路由实例
createWebHashHistory // 路由模式
} from 'vue-router';
import Home from '../views/Home.vue';
import About from '../views/About.vue';const routes = [
{
path: '/', // URL 路径
name: 'Home', // 路由名称(可选,用于命名导航)
component: Home // 对应的组件
},
{
path: '/about',
name: 'About',
component: About
}
];const router = createRouter({
history: createWebHashHistory(), // Hash 模式
routes // 路由配置
})export default router;
关键点来了:
createRouter和createWebHashHistory是 vue-router 的两个核心函数。
Hash 模式 URL 会带/#/,好处是无需服务器配置,兼容性最好。routes数组定义了 URL 到组件的映射。每个路由都有path(路径)、name(名称,方便编程式导航)、component(要渲染的组件)。- 还有另一种 History 模式(
createWebHistory()),URL 不带#,更美观,但需要后端服务器配合处理 404 问题。
| 模式 | API | URL 格式 | 特点 |
|---|---|---|---|
| Hash 模式 | createWebHashHistory() | /#/about | 不需要服务器配置,兼容性好 |
| History 模式 | createWebHistory() | /about | URL 更美观,需要服务器配置 |
五、根组件 App.vue:所有页面的"容器"
复制代码
Home
About
核心部件解析:
:这是 vue-router 注册的全局组件,最终渲染成Home Home。点击它时不会刷新页面,而是通过 Ja vaScript 切换路由,实现无刷新跳转。:路由的出口,匹配到的页面组件会渲染在这里。访问/#/时渲染 Home.vue,访问/#/about时渲染 About.vue——它是动态的,跟随 URL 变化。
六、页面组件:views 目录下的各个"房间"
复制代码
Home
复制代码
About
这两个是最简单的页面组件,目前只有 部分。在实际项目中,可以根据需要添加脚本和样式。
Vue 单文件组件(SFC)三种常见写法:
| 写法 | 示例 | 适用场景 |
|---|---|---|
| 只有 template | ... | 纯展示型页面 |
| template + script | ... | 有交互逻辑的页面 |
| template + script + style | 完整三件套 | 有独立样式的页面 |
七、全局样式:CSS 变量 + 暗黑模式
复制代码/* style.css */
:root {
--text: #6b6375;
--bg: #fff;
--accent: #aa3bff;
/* ... */
color-scheme: light dark;
}@media (prefers-color-scheme: dark) {
:root {
--text: #9ca3af;
--bg: #16171d;
--accent: #c084fc;
/* ... */
}
}
亮点解析:
:root是 CSS 根选择器(匹配),里面定义的--text这样的CSS 变量,可以通过var(--text)在任何地方引用。好处是统一管理颜色,一处修改全局生效。@media (prefers-color-scheme: dark) { ... }是媒体查询,检测用户系统主题偏好。当用户开启暗黑模式时,自动切换 CSS 变量的值,无需一行 Ja vaScript 代码。
八、Vite 配置:构建工具
复制代码// vite.config.js
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'export default defineConfig({
plugins: [vue()],
})
defineConfig提供类型提示,plugins: [vue()]让 Vite 能处理.vue文件。Vite 底层开发时用 esbuild 做预构建,生产构建时用 Rollup,速度比 Webpack 快得多。
| 构建工具 | 开发服务器 | 生产构建 | 特点 |
|---|---|---|---|
| Webpack | 打包后启动 | 打包 | 生态成熟,配置复杂 |
| Vite | 原生 ESM | Rollup | 启动快,配置简单 |
| Turbopack | 原生 ESM | - | Next.js 专用,Rust 实现 |
九、数据流:从 URL 到页面渲染
复制代码用户在浏览器访问 #/about
↓
浏览器加载 index.html,执行 main.js
↓
createApp(App).use(router).mount('#app')
↓
Vue Router 解析 URL 中的 hash:/#/about
↓
匹配到 routes 中 path: '/about' 的配置
↓
渲染 About.vue 组件到 的位置
↓
用户看到 "About" 页面
十、完整对比:传统开发 vs Vue 项目
| 环节 | 传统 DOM 编程 | Vue 组件化开发 |
|---|---|---|
| 页面切换 | 浏览器刷新,重新请求 HTML | router-link 无刷新跳转 |
| 组件复用 | 复制粘贴 HTML | import 引入,直接当标签用 |
| 样式隔离 | 全局污染 | 组件级隔离 |
| 路由管理 | 后端路由,每个 URL 一个 HTML | 前端路由,一个 HTML 动态切换 |
| 构建工具 | 不需要 | Vite/Webpack 处理模块化 |
总结
这个项目虽然简单,但已经搭起了 Vue 开发的完整骨架:
- Vite 提供了极速的开发体验;
- Vue Router 实现了无刷新的页面切换;
- 组件化 让代码可复用、可维护;
- ESM 模块化 让代码结构清晰。
有了这个基础,后面再往里面加状态管理(Pinia)、API 请求(axios)、更多路由守卫,就只是锦上添花了。动手试试吧!
