Skip to content

项目结构

良好的项目结构是 Vue.js 应用成功的基础。本章将介绍如何组织你的 Vue.js 项目,以确保代码的可维护性、可扩展性和团队协作的效率。

推荐的项目结构

以下是一个典型的 Vue.js 项目结构:

my-vue-app/
├── public/
│   ├── index.html
│   └── favicon.ico
├── src/
│   ├── assets/
│   │   ├── images/
│   │   ├── styles/
│   │   └── fonts/
│   ├── components/
│   │   ├── common/
│   │   ├── layout/
│   │   └── ui/
│   ├── composables/
│   ├── directives/
│   ├── plugins/
│   ├── router/
│   │   └── index.js
│   ├── stores/
│   │   └── index.js
│   ├── utils/
│   ├── views/
│   ├── App.vue
│   └── main.js
├── tests/
│   ├── unit/
│   └── e2e/
├── .env
├── .gitignore
├── package.json
├── vite.config.js
└── README.md

目录说明

public/

存放静态资源,这些文件会被直接复制到构建输出目录。

  • index.html - 应用的 HTML 模板
  • favicon.ico - 网站图标
  • 其他静态资源(如图片、字体等)

src/

应用的源代码目录。

assets/

存放需要被构建工具处理的静态资源。

assets/
├── images/          # 图片资源
│   ├── icons/
│   ├── logos/
│   └── backgrounds/
├── styles/          # 样式文件
│   ├── variables.scss
│   ├── mixins.scss
│   ├── base.scss
│   └── components.scss
└── fonts/           # 字体文件

components/

存放可复用的 Vue 组件。

components/
├── common/          # 通用组件
│   ├── BaseButton.vue
│   ├── BaseInput.vue
│   └── BaseModal.vue
├── layout/          # 布局组件
│   ├── Header.vue
│   ├── Footer.vue
│   └── Sidebar.vue
└── ui/              # UI 组件
    ├── Card.vue
    ├── Table.vue
    └── Form.vue

composables/

存放组合式函数(Composition API)。

javascript
// composables/useCounter.js
import { ref } from 'vue'

export function useCounter(initialValue = 0) {
  const count = ref(initialValue)
  
  const increment = () => count.value++
  const decrement = () => count.value--
  const reset = () => count.value = initialValue
  
  return {
    count,
    increment,
    decrement,
    reset
  }
}

directives/

存放自定义指令。

javascript
// directives/focus.js
export const focus = {
  mounted(el) {
    el.focus()
  }
}

plugins/

存放 Vue 插件。

javascript
// plugins/api.js
import axios from 'axios'

export default {
  install(app, options) {
    app.config.globalProperties.$api = axios.create({
      baseURL: options.baseURL
    })
  }
}

router/

存放路由配置。

javascript
// router/index.js
import { createRouter, createWebHistory } from 'vue-router'
import Home from '@/views/Home.vue'

const routes = [
  {
    path: '/',
    name: 'Home',
    component: Home
  },
  {
    path: '/about',
    name: 'About',
    component: () => import('@/views/About.vue')
  }
]

export default createRouter({
  history: createWebHistory(),
  routes
})

stores/

存放状态管理相关文件(Pinia)。

javascript
// stores/user.js
import { defineStore } from 'pinia'

export const useUserStore = defineStore('user', {
  state: () => ({
    user: null,
    isLoggedIn: false
  }),
  
  actions: {
    login(userData) {
      this.user = userData
      this.isLoggedIn = true
    },
    
    logout() {
      this.user = null
      this.isLoggedIn = false
    }
  }
})

utils/

存放工具函数和辅助方法。

javascript
// utils/format.js
export function formatDate(date) {
  return new Intl.DateTimeFormat('zh-CN').format(new Date(date))
}

export function formatCurrency(amount) {
  return new Intl.NumberFormat('zh-CN', {
    style: 'currency',
    currency: 'CNY'
  }).format(amount)
}

views/

存放页面级组件。

views/
├── Home.vue
├── About.vue
├── user/
│   ├── Profile.vue
│   └── Settings.vue
└── admin/
    ├── Dashboard.vue
    └── Users.vue

组件命名规范

基础组件

应用特定样式和约定的基础组件应该全部以一个特定的前缀开头,比如 BaseAppV

components/
├── BaseButton.vue
├── BaseTable.vue
├── BaseIcon.vue
└── BaseInput.vue

单例组件

只拥有单个活跃实例的组件应该以 The 前缀命名,以示其唯一性。

components/
├── TheHeading.vue
├── TheSidebar.vue
└── TheFooter.vue

紧密耦合的组件

和父组件紧密耦合的子组件应该以父组件名作为前缀命名。

components/
├── TodoList.vue
├── TodoListItem.vue
└── TodoListItemButton.vue

文件命名规范

组件文件名

组件文件名应该始终是单词大写开头 (PascalCase)。

✅ 好的
MyComponent.vue
UserProfile.vue
ShoppingCart.vue

❌ 不好的
myComponent.vue
user-profile.vue
shopping_cart.vue

其他文件名

其他 JavaScript 文件使用 camelCase 或 kebab-case。

✅ 好的
utils/formatDate.js
utils/format-date.js
api/userService.js
api/user-service.js

代码组织原则

1. 单一职责原则

每个组件应该只负责一个功能或一组相关的功能。

2. 组件大小

尽量保持组件小而专注,一般建议单个组件不超过 200-300 行代码。

3. 逻辑分离

将业务逻辑从组件中抽离到 composables 或 utils 中。

vue
<!-- 好的做法 -->
<script setup>
import { useUserData } from '@/composables/useUserData'
import { formatDate } from '@/utils/format'

const { user, loading, error } = useUserData()
</script>

4. 样式组织

使用 scoped 样式或 CSS Modules 来避免样式冲突。

vue
<style scoped>
.user-card {
  padding: 1rem;
  border: 1px solid #ddd;
  border-radius: 4px;
}
</style>

环境配置

环境变量

使用 .env 文件管理不同环境的配置。

bash
# .env.development
VITE_API_BASE_URL=http://localhost:3000/api
VITE_APP_TITLE=My App (Development)

# .env.production
VITE_API_BASE_URL=https://api.myapp.com
VITE_APP_TITLE=My App

配置文件

vite.config.js 中配置构建选项。

javascript
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { resolve } from 'path'

export default defineConfig({
  plugins: [vue()],
  resolve: {
    alias: {
      '@': resolve(__dirname, 'src')
    }
  },
  server: {
    port: 3000,
    open: true
  }
})

下一步

现在你已经了解了 Vue.js 项目的基本结构,继续学习:

良好的项目结构是成功的开始,让我们继续构建高质量的 Vue.js 应用!

基于 Vue.js 官方文档构建的学习宝典