Vue 3 + Vite 从零搭建现代前端项目:手把手教你理解整个架构

212 阅读11分钟

前言

前段时间决定系统学习 Vue 3,正好从最基础的项目搭建开始,一步步把整个项目的架构搞清楚。网上很多教程要么直接贴一堆命令,要么直接跳到组件写法,我总觉得缺了点“为什么这么做”的感觉

这次我把自己从零开始搭建一个 Vue 3 + Vite 项目的所有笔记和代码整理了一下,写成这篇文章。目标很简单:让跟你我一样的新手,看完就能明白一个现代 Vue 项目到底长什么样、每一层是干嘛的,以及它是怎么实现前后端分离的

咱们不讲太高深的原理,就从实际代码和文件结构入手,由浅入深,一步步拆解。

一、用 Vite 快速创建一个 Vue 项目

现在 Vue 官方推荐的构建工具不再是 Vue CLI,而是 Vite

Vite 是谁开发的?就是咱们熟悉的 Vue 作者尤雨溪(Evan You)亲自操刀的下一代构建工具。它的最大亮点是开发时启动速度极快 + 热更新(HMR)几乎秒刷新

为什么快?因为它利用了浏览器原生支持的 ES Modules(ESM),开发模式下不需要把所有代码打包成一个大 bundle,浏览器想用哪个模块就直接去请求哪个模块,省掉了大量打包时间。

创建项目命令超级简单:

npm create vite@latest

按提示选择:

  • 项目名:比如 all-vue
  • 框架:Vue
  • 变体:JavaScript(或者 TypeScript,随你)

创建完后:

cd all-vue
npm install
npm run dev

打开浏览器访问 http://localhost:5173,你会看到一个默认的 Vite + Vue 欢迎页。

这一步我们就得到了一个开箱即用、架构清晰的标准 Vue 项目模板

image.png

二、整体架构一览:看这张图就懂了

我自己画了一张简易架构图,帮助大家快速建立全局观:

EB6A6CFE-059B-4EF8-A3BC-039F37EF06B9.png

整个项目就像搭积木一样,一层一层往上叠。

三、项目文件结构详解

创建好的项目大概长这样:

all-vue/
├── index.html          # 整个应用的入口 HTML
├── package.json
├── vite.config.js
├── src/
│   ├── main.js         # 应用入口文件
│   ├── App.vue         # 根组件
│   ├── style.css       # 全局样式
│   ├── components/     # 可复用组件目录
│   ├── views/          # 页面级组件目录(我们后面会加)
│   └── router/         # 路由配置(我们后面会加)
└── public/
    └── vite.svg        # 静态资源

我们一个个文件来看。

1. index.html —— 真正的“首页”

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" type="image/svg+xml" href="/vite.svg" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>all-vue</title>
  </head>
  <body>
    <div id="app"></div>
    <script type="module" src="/src/main.js"></script>
  </body>
</html>

重点看两行:

  • < div id="app">:这就是 Vue 应用将来挂载的根节点。
  • < cript type="module" src="/src/main.js"></ script>:关键!type="module" 说明我们用的是原生 ES Modules,这也是 Vite 能这么快的核心原因。Vite 在开发时直接把这个 script 当作入口启动服务器。

2. src/main.js —— 应用启动入口

import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
import router from './router'  // 后面我们加的路由

createApp(App)
  .use(router)            // 启用路由插件
  .mount('#app')          // 挂载到 index.html 的 #app 上

这就是整个 Vue 应用的启动流程:

  1. 用 createApp 创建一个应用实例(基于根组件 App.vue)
  2. 安装需要的插件(比如 router)
  3. 把应用挂载到 DOM 的 #app 节点上

从这一刻起,页面就完全交给 Vue 管理了,我们再也不用手动操作 DOM(告别原生 DOM 编程)。

3. App.vue —— 根组件

<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></router-view>
  </main>

  <footer></footer>
</template>

<style scoped>
/* 组件局部样式 */
</style>

App.vue 是所有组件的“老大”。我们通常在这里放:

  • 全局布局(header、footer、导航)
  • :路由占位符,哪个页面匹配当前路径,就把哪个页面组件渲染在这里

四、如何实现多页面?—— 引入 vue-router

单页应用(SPA)的核心就是路由。Vue 官方推荐的路由库是 vue-router

安装:

npm install vue-router@4

新建目录结构:

src/
├── views/          # 专门放页面级组件
│   ├── Home.vue
│   └── About.vue
└── router/
    └── index.js    # 路由配置文件

1.Home.vue 和 About.vue(页面组件)

<!-- Home.vue -->
<template>
  <div>Home 页面内容</div>
</template>

<script>
export default {}
</script>

<style lang="scss" scoped>
</style>

About.vue 同理,只是内容换成 About。

2.router/index.js —— 路由配置核心

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({
  history: createWebHashHistory(),  // hash 模式,带 #,简单好用
  routes
})

export default router

大括号里的两个东西:createRouter 和 createWebHashHistory

vue-router 这个包里导出了很多东西,我们只需要其中两个:

  • createRouter 字面意思就是“创建一个路由器”。 它是 vue-router 的核心函数,用来创建路由实例(也就是整个项目的路由管理系统)。 后面我们会调用它:

    const router = createRouter({ ...配置 })
    

    得到一个 router 对象,然后在 main.js 里通过 app.use(router) 把路由功能挂到 Vue 应用上。

  • createWebHashHistory 这个是路由模式的工厂函数,决定你的 URL 长什么样子以及浏览器历史记录怎么管理。 它创建的是 Hash 模式 的历史管理器。

    Hash 模式的特点:

    • URL 中会带一个 #,例如:http://localhost:5173/#/about

    • 后面的部分叫 hash,浏览器不会把 hash 部分发送到服务器。

    • 优点:兼容性最好,部署最简单,直接扔到任何静态服务器(甚至 GitHub Pages)都能正常路由切换,不需要服务器做特殊配置。

    • 缺点:URL 看起来有点“老土”,带个 # 不够美观(不过对新手学习来说完全够用)。

    vue-router 还支持其他模式,比如:

    • createWebHistory() → History 模式(干净的 URL,如 /about),但生产部署时需要服务器配合(否则刷新会 404)。
    • createMemoryHistory() → 内存模式,主要用于 SSR(服务器端渲染)或测试。

    我们这里选 createWebHashHistory 是因为它最简单、最稳。

在main.js中,导入并使用:

import router from './router'
createApp(App).use(router).mount('#app')

现在访问 / 看到 Home,访问 /#/about 看到 About,页面切换完全不刷新,这就是单页应用(SPA)!

/:

image.png

/#/about:

image.png

五、package.json 和 package-lock.json:前端项目的“清单”和“锁单”

在每一个用 npm(或 yarn、pnpm)管理的现代前端项目里,你都会看到这两个文件:package.jsonpackage-lock.json。它们长得很像,但作用完全不一样。我们用项目里的内容来通俗讲解一下。

1. package.json —— 项目清单(人为维护的“购物清单”)

这是项目最核心的配置文件,由我们自己(或创建工具)手动维护。

你的 package.json 内容:

{
  "name": "all-vue",
  "private": true,
  "version": "0.0.0",
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "preview": "vite preview"
  },
  "dependencies": {
    "vue": "^3.5.24",
    "vue-router": "^4.6.4"
  },
  "devDependencies": {
    "@vitejs/plugin-vue": "^6.0.1",
    "vite": "^7.2.4"
  }
}

它主要记录了以下几类信息:

  • 项目基本信息:名字(name)、版本(version)、是否私有(private)

  • 运行脚本(scripts) : 你平时敲的命令其实都是这里定义的:

    • npm run dev → 执行 vite(启动开发服务器)
    • npm run build → 执行 vite build(打包生产代码)
    • npm run preview → 执行 vite preview(本地预览打包后的项目)
  • 依赖包(dependencies) : 项目运行时真正需要的包(上线后用户也会用到):

    • vue: Vue 3 核心框架
    • vue-router: 路由库
  • 开发依赖(devDependencies) : 只在开发时需要的包(打包后不会带到生产环境):

    • vite: 构建工具本身
    • @vitejs/plugin-vue: Vite 的 Vue 插件,让 Vite 能正确处理 .vue 文件
  • type: "module" :告诉 Node.js 这个项目使用 ES Module 语法(import/export),而不是老的 CommonJS(require/module.exports)

总结

package.json 就像你的“购物清单”,写清楚了“我这个项目要用哪些包,大概版本要多少”。

注意里面的版本号前面有 ^(脱字符号),表示允许小版本和补丁版本自动更新,比如 ^3.5.24 可以接受 3.5.x 到 3.6.0 以下的版本,但不会跳到 4.x。

2. package-lock.json —— 依赖锁文件(自动生成的“收据”)

这个文件非常长(你提供的就已经被截断了,实际可能有几万行),它是由 npm 自动生成和维护的,我们一般不手动修改它。

它的作用是:精确记录当前项目里每一个依赖包的具体版本、下载地址、完整依赖树以及完整性校验值

在我的文件中可以看到:

  • vue 实际安装的是 3.5.25(比 package.json 里写的 ^3.5.24 高了一点)
  • vite 实际安装的是 7.3.0(比 ^7.2.4 高)
  • 还有一大堆底层依赖(如 @babel/parser、esbuild 各种平台的二进制包等)的精确版本和下载源(这里用了 npmmirror.com 镜像)

为什么需要这个锁文件?

想象一下:

  • 你今天 npm install,装好了 vue@3.5.25 和 vite@7.3.0,项目能正常跑。
  • 过三个月,你或你的同事在新电脑上重新 npm install,如果没有 package-lock.json,npm 会去下载当时最新的符合 ^3.5.24 的版本,可能已经是 3.6.x 或更高,导致项目行为不一致,甚至出错。
  • 有了 package-lock.json,npm 会严格按照里面记录的版本(比如必须是 3.5.25)去安装,保证每一次安装的结果都完全一样

这就是“锁版本”的意思,确保团队成员、本地开发、CI/CD 服务器、生产部署的环境完全一致。

两者最主要的区别总结

项目package.jsonpackage-lock.json
谁维护人为维护(我们自己改)npm 自动生成和更新(我们不手动改)
内容粗略版本范围(带 ^ 或 ~)精确到具体小版本(如 3.5.25)
大小很小(几十行)很大(几千甚至上万行)
作用声明项目需要哪些依赖锁定所有依赖的精确版本和依赖树,确保一致性
是否提交到 Git必须提交必须提交(非常重要!)
运行 npm install 时根据这里去解析版本范围,然后下载最新符合的版本优先读取这里,直接安装锁定的精确版本
可以手动修改吗可以,也应该改(加新包、改版本)不建议手动改(容易出问题)

实际开发中的建议

  1. 永远把这两个文件都提交到 Git 仓库(尤其是 package-lock.json)。

  2. 当你想添加新依赖时:

    • 运行 npm install vue-router --save(会自动加到 dependencies)
    • 或 npm install vite-plugin-inspect --save-dev(加到 devDependencies)
    • npm 会自动更新 package.json 和 package-lock.json
  3. 看到别人项目里有 package-lock.json,就放心克隆下来 npm install,环境一定和别人一模一样。

简单记一句话:

  • package.json 是你告诉 npm “我要买这些东西,大概这个牌子就行”。
  • package-lock.json 是 npm 给你开的“详细收据”,写清楚了“我到底买了哪个具体版本,从哪儿买的,下次还买一样的”。

理解了这两个文件的区别,你就真正掌握了现代前端项目依赖管理的第一步!

六、前后端分离到底是怎么实现的?

很多人新手时最困惑的一点:Vue 项目怎么跟后端配合?为什么叫前后端分离?

简单来说:

  • 传统后端渲染:用户访问一个 URL → 后端(Java、PHP 等)直接返回一个完整的 HTML 页面(里面已经把数据渲染好了)。
  • 前后端分离(SPA) :用户访问任何一个 URL,都先返回同一个 index.html(里面只有一个空
    ),然后由前端 Vue 通过 JavaScript 把页面内容动态渲染出来。

数据从哪里来?前端通过 Ajax / fetch / axios 向后端提供的 API 接口(通常是 RESTful 或 GraphQL)请求 JSON 数据,然后把数据渲染到页面上。

优势:

  1. 前端路由完全由 vue-router 掌控,用户切换页面体验像原生 App 一样流畅(不白屏)。
  2. 前后端职责清晰:后端只负责提供数据接口,前端负责页面展示和交互。
  3. 部署简单:前端项目打包后就是一堆静态文件(html/js/css),扔到 Nginx 或 CDN 上就行,后端接口部署在另一台服务器。

在我们这个项目里:

  • 开发阶段:Vite 启动一个本地 dev server(localhost:5173),代理 API 请求到后端(vite.config.js 可以配置 proxy)
  • 生产打包:运行 npm run build,会生成 dist 目录,里面全是静态文件,直接部署即可。

七、开发体验加分项:两个实用插件

  1. Volar(VS Code 插件)

    • Vue 官方出品,取代了旧的 Vetur
    • 提供 < script setup> 语法的高亮、自动补全、类型提示
    • 安装后你的 Vue 单文件组件写起来会非常舒服
  2. Vue Devtools(Chrome/Firefox 插件)

    • 可以直接在浏览器开发者工具里看到组件树、Vuex 状态、路由信息
    • 调试 Vue 项目必备神器

总结:一个现代 Vue 项目的完整架构思维导图

  • 底层基石:Node.js + npm 管理依赖
  • 构建工具:Vite 负责开发服务器、热更新、打包
  • 核心框架:Vue 3(组件化、响应式)
  • 路由层:vue-router 实现单页应用多页面切换
  • 状态管理(进阶):Vuex / Pinia(本文暂不展开)
  • 开发工具:Volar + Vue Devtools 提升效率
  • 部署方式:打包成静态文件,实现彻底前后端分离

掌握了这些,你就已经站在现代前端工程化的起跑线上了。

接下来你可以:

  • 在 components 里写各种可复用组件
  • 在 views 里添加更多页面
  • 引入 Element Plus / Ant Design Vue 等 UI 库
  • 学 Pinia 做全局状态管理
  • 配置代理跨域,真正连上后端接口