3、项目结构解析:Vue项目目录结构、package.json解读、main.js入口文件、App.vue根组件

好,项目跑起来了,页面也看到了。但说实话,很多新手这时候反而会懵——这文件夹里一堆东西都是干嘛的?我当年第一次用脚手架创建项目时,盯着屏幕看了十分钟,愣是没敢动。别急,今天我就带你把这几个核心文件挨个捋一遍。

3.1 项目目录结构:先认个脸熟

create-vue 创建的项目,默认长这样:

my-vue-app/
├── node_modules/        # 依赖包(别手动改)
├── public/              # 静态资源(不会被编译)
│   └── favicon.ico
├── src/                 # 源码目录(你主要待的地方)
│   ├── assets/          # 图片、字体等资源
│   ├── components/      # 组件文件夹
│   ├── App.vue          # 根组件
│   └── main.js          # 入口文件
├── index.html           # 页面模板
├── package.json         # 项目配置文件
├── vite.config.js       # Vite 构建配置
└── README.md            # 项目说明

嗯,这里要注意:node_modules 千万别手贱去改。我见过有同学直接在里面改代码,结果重新安装依赖后全丢了。这个文件夹是 npm 自动管理的,你只管用,别碰它。

真正需要你关心的,其实就三个地方:src 目录、package.jsonindex.html。咱们一个一个说。

3.2 package.json:项目的身份证

打开 package.json,你会看到类似这样的内容:

{
  "name": "my-vue-app",
  "version": "0.0.0",
  "private": true,
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "preview": "vite preview"
  },
  "dependencies": {
    "vue": "^3.4.0"
  },
  "devDependencies": {
    "@vitejs/plugin-vue": "^5.0.0",
    "vite": "^5.0.0"
  }
}

这个文件说白了就是项目的「说明书+清单」。它告诉系统三件事:

  • 项目叫什么name)—— 发布到 npm 时用得到
  • 怎么运行scripts)—— npm run dev 就是执行这里的命令
  • 依赖了谁dependencies / devDependencies)—— 生产环境和开发环境分别需要哪些包

重点区分:

  • dependencies:项目运行时必须的,比如 Vue 本身
  • devDependencies:开发时才需要,比如 Vite 构建工具、ESLint 等

我个人习惯是,每次拿到新项目先看 package.json。为什么?因为从这里能快速知道项目用了哪些技术栈、版本号是多少。有一次我接手一个老项目,发现 Vue 还是 2.x 版本,赶紧确认了一下兼容性,避免踩坑。

3.3 main.js:一切从这里开始

打开 src/main.js,内容非常精简:

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

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

就三行代码,但它是整个应用的「总开关」。我来拆解一下:

  1. createApp:Vue 提供的工厂函数,用来创建一个应用实例
  2. App:从 App.vue 导入的根组件,相当于应用的「根」
  3. .mount('#app'):把应用挂载到 index.html 中 id 为 app 的 DOM 元素上

你想想看,这就像盖房子——createApp 是打地基,App.vue 是主体结构,mount 就是把房子放到指定位置。顺序不能乱,少一步都不行。

小技巧:如果你需要全局注册组件或插件(比如 Vue Router、Pinia),通常就在 main.jscreateApp 之后、mount 之前插入。比如:

const app = createApp(App)
app.use(router)  // 注册路由
app.mount('#app')

3.4 App.vue:根组件的真面目

打开 src/App.vue,默认长这样:

<template>
  <div id="app">
    <h1>Hello Vue!</h1>
  </div>
</template>

<script setup>
// 这里写逻辑
</script>

<style scoped>
/* 这里写样式 */
</style>

一个 .vue 文件由三部分组成,我管它叫「三明治结构」:

部分 标签 作用
模板 <template> 写 HTML 结构,决定页面长什么样
脚本 <script setup> 写 JavaScript 逻辑,处理数据、事件等
样式 <style scoped> 写 CSS,scoped 表示样式只作用于当前组件

注意那个 scoped 属性——我曾经在项目里忘了加它,结果样式污染了全局,排查了半天才发现。加上 scoped 后,Vue 会自动给每个元素加一个唯一属性,确保样式不会「越界」。

避坑指南:如果你在 <style> 里不加 scoped,样式就是全局的。虽然方便,但大型项目里很容易造成样式冲突。我的建议是:默认都加 scoped,除非你明确需要全局样式。

3.5 它们是怎么串起来的?

好,现在我们把整个流程串一遍:

  1. 浏览器打开 index.html,里面有个 <div id="app"></div>
  2. main.js 执行,调用 createApp(App) 创建 Vue 应用
  3. 应用被挂载到 #app 这个 div 上
  4. App.vue 里的模板内容替换掉那个 div
  5. 页面就渲染出来了

说白了,index.html 是个空壳子,main.js 是启动器,App.vue 才是真正的内容。你后续写的所有组件,最终都会挂到 App.vue 下面,形成一棵组件树。

嗯,到这里你应该对项目结构心里有数了。下一章我们开始动手写第一个真正的组件,到时候你会更深刻地理解「组件化」到底是什么意思。