概述

Vue.js 作为当前最流行的前端框架之一,拥有完整的生态系统和丰富的技术栈。本文总结了 Vue 开发中的主流技术栈和最佳实践。

核心技术栈

1. Vue 3 + Composition API

为什么选择 Vue 3?

  • 更好的性能(重写了虚拟 DOM)
  • 更好的 TypeScript 支持
  • Composition API 提供更灵活的代码组织方式
  • Tree-shaking 友好,打包体积更小

最佳实践:

// 推荐使用 <script setup> 语法糖
<script setup>
import { ref, computed, onMounted } from 'vue'

const count = ref(0)
const doubled = computed(() => count.value * 2)

onMounted(() => {
  console.log('组件已挂载')
})
</script>

2. 构建工具

Vite(推荐)

  • 极快的冷启动速度
  • 即时的模块热更新(HMR)
  • 开箱即用的 TypeScript 支持
  • 优化的生产构建
# 创建 Vite 项目
npm create vite@latest my-vue-app -- --template vue
cd my-vue-app
npm install
npm run dev

Webpack(传统方案)

  • Vue CLI 基于 Webpack
  • 适合需要复杂配置的大型项目

3. 状态管理

Pinia(官方推荐)

  • Vue 3 官方推荐的状态管理库
  • 更轻量,更简洁的 API
  • 完整的 TypeScript 支持
  • 支持开发工具调试
// stores/counter.js
import { defineStore } from 'pinia'

export const useCounterStore = defineStore('counter', {
  state: () => ({
    count: 0
  }),
  getters: {
    doubleCount: (state) => state.count * 2
  },
  actions: {
    increment() {
      this.count++
    }
  }
})

// 组件中使用
<script setup>
import { useCounterStore } from '@/stores/counter'
const counter = useCounterStore()
</script>

Vuex(经典方案)

  • 适合已有项目的维护
  • Vue 2 的标准状态管理方案

4. 路由管理

Vue Router 4

  • Vue 3 官方路由解决方案
  • 支持嵌套路由、动态路由、路由守卫
// router/index.js
import { createRouter, createWebHistory } from 'vue-router'

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

const router = createRouter({
  history: createWebHistory(),
  routes
})

export default router

最佳实践:

  • 使用路由懒加载优化首屏加载速度
  • 合理使用路由守卫进行权限控制
  • 使用命名路由提高可维护性

5. UI 组件库

Element Plus

  • Element UI 的 Vue 3 版本
  • 组件丰富,适合后台管理系统
npm install element-plus

Ant Design Vue

  • Ant Design 的 Vue 实现
  • 企业级 UI 设计语言

Naive UI

  • 完整的 TypeScript 支持
  • 轻量、主题可定制

Vuetify

  • Material Design 风格
  • 组件丰富

选择建议:

  • 后台管理系统:Element Plus / Ant Design Vue
  • 移动端项目:Vant
  • 追求轻量和定制:Naive UI

6. CSS 解决方案

Tailwind CSS(推荐)

  • 原子化 CSS 框架
  • 高度可定制
  • 与 Vue 3 配合完美
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p

SCSS/SASS

  • 传统 CSS 预处理器
  • 支持变量、嵌套、混入
<style lang="scss" scoped>
$primary-color: #42b983;

.container {
  color: $primary-color;
  
  .item {
    padding: 10px;
  }
}
</style>

CSS Modules

  • 避免样式冲突
  • 局部作用域

7. TypeScript

强烈推荐在 Vue 3 项目中使用 TypeScript

<script setup lang="ts">
import { ref, computed } from 'vue'

interface User {
  id: number
  name: string
}

const user = ref<User>({
  id: 1,
  name: 'John'
})

const greeting = computed<string>(() => `Hello, ${user.value.name}`)
</script>

8. HTTP 请求

Axios

  • 最流行的 HTTP 客户端
  • 支持拦截器、请求/响应转换
// utils/request.js
import axios from 'axios'

const request = axios.create({
  baseURL: import.meta.env.VITE_API_BASE_URL,
  timeout: 5000
})

// 请求拦截器
request.interceptors.request.use(
  config => {
    const token = localStorage.getItem('token')
    if (token) {
      config.headers.Authorization = `Bearer ${token}`
    }
    return config
  },
  error => Promise.reject(error)
)

// 响应拦截器
request.interceptors.response.use(
  response => response.data,
  error => {
    console.error('请求失败:', error)
    return Promise.reject(error)
  }
)

export default request

VueUse(工具库)

  • 提供大量组合式 API 工具函数
  • 包括 useFetchuseLocalStorage
import { useFetch } from '@vueuse/core'

const { data, error, isFetching } = useFetch('/api/users')

9. 代码规范工具

ESLint + Prettier

npm install -D eslint prettier eslint-config-prettier eslint-plugin-vue

.eslintrc.js

module.exports = {
  extends: [
    'plugin:vue/vue3-recommended',
    'prettier'
  ],
  rules: {
    'vue/multi-word-component-names': 'off'
  }
}

Husky + lint-staged

  • Git 提交前自动检查代码
npm install -D husky lint-staged
npx husky install

10. 测试工具

Vitest(推荐)

  • Vite 原生支持
  • 与 Jest API 兼容
  • 速度极快

Vue Test Utils

  • Vue 官方测试工具库
import { mount } from '@vue/test-utils'
import HelloWorld from './HelloWorld.vue'

test('displays message', () => {
  const wrapper = mount(HelloWorld, {
    props: {
      msg: 'Hello Vitest'
    }
  })
  expect(wrapper.text()).toContain('Hello Vitest')
})

完整技术栈推荐

方案一:现代化技术栈(推荐)

Vue 3 + TypeScript + Vite + Pinia + Vue Router 4 + 
Element Plus + Tailwind CSS + Axios + VueUse + 
ESLint + Prettier + Vitest

方案二:企业级技术栈

Vue 3 + TypeScript + Vite + Pinia + Vue Router 4 + 
Ant Design Vue + SCSS + Axios + 
ESLint + Prettier + Husky + Jest

方案三:轻量级技术栈

Vue 3 + Vite + Pinia + Vue Router 4 + 
Naive UI + Tailwind CSS + Axios + VueUse

项目结构最佳实践

src/
├── assets/          # 静态资源
│   ├── images/
│   └── styles/
├── components/      # 通用组件
│   ├── common/      # 基础组件
│   └── business/    # 业务组件
├── views/           # 页面组件
├── router/          # 路由配置
├── stores/          # 状态管理
├── api/             # API 接口
├── utils/           # 工具函数
├── composables/     # 组合式函数
├── directives/      # 自定义指令
├── plugins/         # 插件
├── types/           # TypeScript 类型定义
├── App.vue
└── main.ts

开发最佳实践

1. 组件设计原则

  • 单一职责:每个组件只做一件事
  • Props Down, Events Up:父组件通过 props 传递数据,子组件通过事件通知父组件
  • 合理拆分组件:避免单个组件过大
  • 使用组合式函数:复用逻辑

2. 性能优化

// 1. 使用 v-memo 缓存渲染结果(Vue 3.2+)
<div v-memo="[value1, value2]">
  <!-- 只有 value1 或 value2 变化时才重新渲染 -->
</div>

// 2. 使用 defineAsyncComponent 异步组件
import { defineAsyncComponent } from 'vue'

const AsyncComp = defineAsyncComponent(() =>
  import('./components/AsyncComponent.vue')
)

// 3. 使用 KeepAlive 缓存组件
<KeepAlive>
  <component :is="currentComponent" />
</KeepAlive>

// 4. 使用 shallowRef 和 shallowReactive 减少响应式开销
import { shallowRef } from 'vue'
const state = shallowRef({ count: 0 })

3. 代码组织

// 使用组合式函数封装逻辑
// composables/useCounter.js
import { ref, computed } from 'vue'

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

// 组件中使用
<script setup>
import { useCounter } from '@/composables/useCounter'
const { count, doubled, increment, decrement } = useCounter(10)
</script>

4. 环境变量管理

# .env.development
VITE_API_BASE_URL=http://localhost:3000
VITE_APP_TITLE=开发环境

# .env.production
VITE_API_BASE_URL=https://api.example.com
VITE_APP_TITLE=生产环境
// 使用环境变量
const apiUrl = import.meta.env.VITE_API_BASE_URL

5. 错误处理

// main.ts
app.config.errorHandler = (err, instance, info) => {
  console.error('全局错误:', err)
  console.log('错误组件:', instance)
  console.log('错误信息:', info)
  // 可以上报到错误监控平台
}

学习资源

总结

选择技术栈时需要考虑:

  1. 项目规模:小型项目选择轻量方案,大型项目选择完整方案
  2. 团队熟悉度:优先选择团队熟悉的技术
  3. 长期维护性:选择社区活跃、文档完善的技术
  4. 性能要求:根据性能需求选择合适的工具

最重要的是保持技术栈的一致性和简洁性,避免过度工程化。