Vue3 目录结构(手把手讲解)

Vue3 目录结构:从零开始理解项目骨架

当你第一次接触 Vue 3 项目时,看到那个整齐的文件夹结构,是不是有点懵?别急,这就像第一次打开一台新电脑,虽然界面陌生,但只要了解了各个文件夹的“职责”,就能快速上手。今天我们就来拆解 Vue3 目录结构,帮你彻底搞懂每个文件是干什么的。

Vue3 目录结构的设计,是 Vue 团队多年经验的沉淀。它不仅让项目更清晰,也方便团队协作和后期维护。理解这个结构,等于掌握了 Vue 项目开发的“地图”。


项目根目录概览

一个标准的 Vue 3 项目,根目录通常包含以下核心文件和文件夹:

my-vue-project/
├── public/
├── src/
├── .gitignore
├── babel.config.js
├── package.json
├── README.md
├── vite.config.js
└── vite.config.ts

这些文件和文件夹共同构成了 Vue 3 项目的基础。接下来我们逐个剖析它们的用途。

public 文件夹:静态资源的“大本营”

public 文件夹是项目中所有静态资源的存放地。比如 HTML 模板、favicon 图标、图片、字体等。这个文件夹里的内容不会经过构建工具处理,会直接复制到输出目录。

<!-- public/index.html -->
<!DOCTYPE html>
<html lang="zh">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>我的 Vue 3 项目</title>
  <!-- 这里的 meta 标签用于响应式设计 -->
  <!-- favicon 会自动从 public 文件夹读取 -->
</head>
<body>
  <!-- 挂载点,Vue 会把应用渲染到这里 -->
  <div id="app"></div>
</body>
</html>

注释:index.html 是整个应用的入口文件。id="app" 这个 div 是 Vue 应用的挂载点,相当于“舞台”,所有组件都会在这里渲染。

src 文件夹:项目的核心“作战室”

src 文件夹是 Vue 项目中最重要的部分,所有源代码都放在这里。我们通常说的“开发工作”就在这里进行。


src 目录结构详解

src 目录是 Vue3 项目的大脑,它的结构决定了代码的组织方式。以下是常见结构:

src/
├── assets/
├── components/
├── views/
├── router/
├── store/
├── composables/
├── App.vue
├── main.js
└── App.css

我们逐个来看。

assets 文件夹:资源的“仓库”

assets 文件夹用于存放项目中使用的图片、样式文件、字体等资源。这些资源会经过构建工具处理,比如压缩、路径替换。

/* src/assets/styles/theme.css */
/* 定义全局主题变量,便于统一管理 */
:root {
  --primary-color: #42b983;   /* 主色调:绿色 */
  --text-color: #333;         /* 文字颜色 */
  --bg-color: #f9f9f9;        /* 背景色 */
}

注释:这个 CSS 文件定义了全局变量,可以在其他组件中通过 var(--primary-color) 使用。这样一旦改颜色,只需改一个地方。

components 文件夹:可复用的“乐高积木”

components 文件夹存放的是可复用的组件。比如按钮、卡片、导航栏等。这些组件就像乐高积木,可以拼出各种复杂的页面。

<!-- src/components/CustomButton.vue -->
<template>
  <!-- 使用 v-bind 动态绑定按钮样式 -->
  <button :class="['btn', type]" @click="handleClick">
    <!-- 插槽,允许父组件传入内容 -->
    <slot>点击我</slot>
  </button>
</template>

<script setup>
// 使用 defineProps 定义组件接收的参数
const props = defineProps({
  type: {
    type: String,
    default: 'primary',
    validator: (val) => ['primary', 'secondary', 'danger'].includes(val)
  }
})

// 定义点击事件
const emit = defineEmits(['click'])

const handleClick = () => {
  emit('click')
}
</script>

<style scoped>
/* scoped 表示样式只作用于当前组件 */
.btn {
  padding: 8px 16px;
  border: none;
  border-radius: 4px;
  font-size: 14px;
  cursor: pointer;
}

.btn.primary {
  background-color: var(--primary-color);
  color: white;
}

.btn.secondary {
  background-color: #6c757d;
  color: white;
}

.btn.danger {
  background-color: #dc3545;
  color: white;
}
</style>

注释:这个组件支持动态类型(primary/secondary/danger),通过 defineProps 接收参数,用 defineEmits 触发事件。<slot> 允许父组件传入文字内容,非常灵活。


Views 与路由:页面的“地图”

在 Vue 项目中,views 文件夹通常用来存放页面级别的组件。比如首页、用户中心、设置页等。它们通常是路由的“目标”。

router 文件夹:页面跳转的“导航系统”

router 文件夹负责管理页面之间的跳转逻辑。Vue 3 推荐使用 Vue Router 4。

// src/router/index.js
import { createRouter, createWebHistory } from 'vue-router'
import HomeView from '../views/HomeView.vue'
import AboutView from '../views/AboutView.vue'

// 定义路由表:路径 → 组件映射
const routes = [
  {
    path: '/',
    name: 'home',
    component: HomeView
  },
  {
    path: '/about',
    name: 'about',
    component: AboutView
  }
]

// 创建路由器实例
const router = createRouter({
  history: createWebHistory(),
  routes
})

export default router

注释:createWebHistory() 使用 HTML5 History API,让 URL 看起来更“自然”(比如 /about 而不是 /#/about)。routes 数组定义了所有可访问的页面路径。

store 文件夹:状态管理的“中央仓库”

当项目复杂到需要多个组件共享数据时,store 文件夹就派上用场了。Vue 3 推荐使用 Pinia 作为状态管理工具。

// src/store/userStore.js
import { defineStore } from 'pinia'

// 定义一个名为 useUserStore 的 Store
export const useUserStore = defineStore('user', {
  state: () => ({
    name: '',
    email: '',
    isLoggedIn: false
  }),

  // 可以定义方法来修改状态
  actions: {
    login(userData) {
      this.name = userData.name
      this.email = userData.email
      this.isLoggedIn = true
    },

    logout() {
      this.$reset() // 重置状态
    }
  },

  // 可选:持久化存储(比如存到 localStorage)
  persist: true
})

注释:defineStore 创建一个状态容器。state 定义初始数据,actions 是修改数据的方法。persist: true 表示数据会自动保存到浏览器本地存储。


Composables:逻辑复用的“工具箱”

composables 文件夹是 Vue 3 新增的特性。它用于存放可复用的逻辑函数,比如表单验证、数据获取、本地存储操作等。

// src/composables/useLocalStorage.js
import { ref, watch } from 'vue'

// 自定义组合式函数:用于操作本地存储
export function useLocalStorage(key, initialValue) {
  // 从 localStorage 读取数据,如果不存在则使用默认值
  const storedValue = localStorage.getItem(key)
  const value = storedValue ? JSON.parse(storedValue) : initialValue

  // 使用 ref 创建响应式数据
  const localValue = ref(value)

  // 监听值变化,自动保存到 localStorage
  watch(localValue, (newValue) => {
    localStorage.setItem(key, JSON.stringify(newValue))
  })

  return localValue
}

注释:这个函数封装了“读写 localStorage”的逻辑。调用时传入键名和默认值,返回一个响应式变量。任何修改都会自动保存,非常方便。


main.js 与 App.vue:应用的“心脏”

main.js:应用的入口

main.js 是整个 Vue 应用的启动文件。

// src/main.js
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'

// 创建应用实例
const app = createApp(App)

// 挂载路由和状态管理
app.use(router)
app.use(store)

// 挂载到 DOM 上
app.mount('#app')

注释:createApp(App) 创建一个 Vue 应用实例。use(router)use(store) 把路由和状态管理注入到应用中。最后 mount('#app') 把应用挂载到 HTML 中的 #app 元素上。

App.vue:根组件

App.vue 是所有组件的“父容器”。

<!-- src/App.vue -->
<template>
  <div id="app">
    <!-- 使用路由链接进行页面跳转 -->
    <nav>
      <router-link to="/">首页</router-link>
      <router-link to="/about">关于</router-link>
    </nav>

    <!-- 路由视图:显示匹配的页面 -->
    <router-view />
  </div>
</template>

<script setup>
// 这里可以写根组件的逻辑
// 通常用于全局状态监听或事件处理
</script>

<style>
/* 全局样式 */
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  text-align: center;
  margin-top: 60px;
}
</style>

注释:<router-link> 用于导航,<router-view> 是页面内容的占位符。当路径变化时,会自动渲染对应的组件。


总结:理解 Vue3 目录结构,就是掌握开发节奏

Vue3 目录结构并不是随意设计的,而是经过深思熟虑的工程化产物。它把“资源”“逻辑”“页面”“状态”分门别类,让开发更高效,维护更轻松。

publicsrc,从 componentsstore,每一个文件夹都有明确的职责。理解它们,就等于掌握了 Vue 项目开发的“方法论”。

当你以后看到一个新项目时,不用慌,先看目录结构,就像侦探找线索。你会发现:原来每个文件都各司其职,整个系统井然有序。

记住:好的项目结构,不是为了好看,而是为了让代码“活得久”。当你能读懂一个 Vue3 目录结构,你就已经迈出了成为专业前端工程师的第一步。