前言

在前两篇文章中,我们已经:

  • ✅ 明确了 Vue3 是必须掌握的技能

  • ✅ 完成了 Vite + Vue3 + TypeScript 的环境搭建

但很多初学者在创建完项目后,面对一堆目录和文件依然会感到困惑:

main.ts到底做了什么?

❓ 为什么 HTML 放在根目录?

❓ 组件应该怎么组织才合理?

这一篇,我们就逐层拆解 Vue3 项目结构,并在此基础上建立正确的组件化思维


一、Vue3 + Vite 项目整体结构

使用 pnpm create vite创建的项目,默认结构如下:

my-vue3-app
├── .vscode/              # VS Code 配置(可选)
├── node_modules/
├── public/              # 静态资源(不经过 Vite 处理)
├── src/                 # 源码核心目录
│   ├── assets/          # 图片、字体等资源
│   ├── components/      # 公共组件
│   ├── views/           # 页面级组件(可选)
│   ├── router/          # 路由配置(后续章节)
│   ├── store/           # 状态管理(Pinia)
│   ├── utils/           # 工具函数
│   ├── App.vue          # 根组件
│   └── main.ts          # 应用入口
├── index.html           # 入口 HTML
├── package.json
├── tsconfig.json
└── vite.config.ts       # Vite 配置

二、index.html:真正的入口

1️⃣ Vue3 与 Vue2 的最大不同

Vue2(Vue CLI)

Vue3(Vite)

HTML 被 Webpack 隐藏

✅ HTML 显式存在

自动注入 JS

✅ 手动引入入口脚本

<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" href="/favicon.ico" />
    <title>Vue3 App</title>
  </head>
  <body>
    <div id="app"></div>
    <script type="module" src="/src/main.ts"></script>
  </body>
</html>

📌 关键点

  • #app只是挂载点

  • main.ts通过原生 ES Module 加载

  • 更符合现代浏览器标准


三、main.ts:应用的起点

import { createApp } from 'vue'
import App from './App.vue'

createApp(App).mount('#app')

1️⃣ 逐行解析

代码

含义

createApp(App)

创建 Vue 应用实例

mount('#app')

挂载到 DOM

2️⃣ 与 Vue2 的本质区别

// Vue2
new Vue({
  render: h => h(App)
}).$mount('#app')

✅ Vue3 的优势:

  • 没有全局 Vue 构造函数

  • 每个应用都是独立实例

  • 插件注册不会影响全局


四、App.vue:根组件的演变

1️⃣ 默认结构

<template>
  <HelloWorld msg="Vue3 + Vite" />
</template>

<script setup lang="ts">
import HelloWorld from './components/HelloWorld.vue'
</script>

2️⃣ Vue3 的关键变化

变化点

说明

<script setup>

更简洁的组合式写法

不需要 export default

默认导出由编译器完成

组件自动注册

import 即使用


五、src 目录结构详解(重点)

1️⃣ assets:资源文件

assets/
├── images/
├── fonts/
└── styles/

✅ 特点:

  • 会被 Vite 处理(压缩、hash)

  • 适合放图片、字体、全局样式


2️⃣ components:公共组件

components/
├── Button/
│   ├── BaseButton.vue
│   └── index.ts
├── Input/
└── common/

✅ 建议:

  • 一个组件一个目录

  • 配套 index.ts 统一导出

  • 提高可维护性


3️⃣ views / pages(推荐约定)

views/
├── Home/
│   ├── index.vue
│   └── components/
├── About/
└── User/

📌 区分原则:

  • views:页面级组件(对应路由)

  • components:可复用的 UI 组件


4️⃣ router / store / utils

目录

作用

router

Vue Router 配置

store

Pinia 状态管理

utils

请求封装、工具函数


六、组件化思维:Vue3 开发的灵魂

1️⃣ 什么是组件化?

一句话概括:

把 UI 拆成独立、可复用、职责单一的单位。

2️⃣ 组件划分原则

单一职责原则

  • 一个组件只做一件事

可复用性

  • 通用 UI 抽成公共组件

层级清晰

  • 页面组件 ≠ UI 组件

3️⃣ 示例:一个典型组件结构

<template>
  <div class="user-card">
    <img :src="avatar" />
    <h3>{{ name }}</h3>
  </div>
</template>

<script setup lang="ts">
defineProps<{
  avatar: string
  name: string
}>()
</script>

<style scoped>
.user-card {
  padding: 16px;
}
</style>

七、项目结构常见误区

误区

正确做法

所有组件都放 components

views 单独管理页面

一个文件写多个组件

一个文件一个组件

业务逻辑写在 App.vue

拆分到 views / store

样式全局污染

使用 scoped或 CSS Modules


📢 下期预告

👉 第 04 篇:Vue3 响应式原理初探 —— 从 Object.defineProperty 到 Proxy

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐