Vue 前端开发

难度等级:⭐⭐⭐ 前置知识:编程语言基础、Web 基础 后续衔接:架构设计、工程化

学习路径


一、Vue 核心概念

1.1 响应式原理

Vue 的核心特性是响应式系统,能够自动追踪数据变化并更新视图。Vue 3 使用 Proxy 实现响应式,相比 Vue 2 的 Object.defineProperty 有显著改进。

核心要点

代码示例

import { ref, reactive, computed, watch } from 'vue'

// ref 用于基本类型
const count = ref(0)
count.value++ // 触发更新

// reactive 用于对象
const state = reactive({
  user: { name: 'Vue', age: 10 },
  items: [1, 2, 3]
})
state.user.name = 'Vue 3' // 触发更新

// computed 缓存计算结果
const doubleCount = computed(() => count.value * 2)

// watch 监听变化执行副作用
watch(count, (newVal, oldVal) => {
  console.log(`Count changed from ${oldVal} to ${newVal}`)
})

关联知识点:Proxy、依赖收集、发布-订阅模式

1.2 组件系统

组件是 Vue 应用的基本构建块,每个组件封装了模板、逻辑和样式。

核心要点

代码示例

<!-- ProductCard.vue -->
<script setup lang="ts">
interface Props {
  product: {
    id: number
    name: string
    price: number
  }
  discount?: number
}

const props = withDefaults(defineProps<Props>(), {
  discount: 0
})

const emit = defineEmits<{
  add: [product: Props['product']]
  remove: [id: number]
}>()

const finalPrice = computed(() => {
  return props.product.price * (1 - props.discount / 100)
})
</script>

<template>
  <div class="product-card">
    <h3>{{ product.name }}</h3>
    <p>价格: ¥{{ finalPrice }}</p>
    <button @click="emit('add', product)">加入购物车</button>
  </div>
</template>

关联知识点:单向数据流、组件通信、TypeScript

1.3 生命周期

Vue 组件从创建到销毁经历一系列生命周期钩子,开发者可在特定阶段执行逻辑。

核心要点

代码示例

import { onMounted, onUnmounted, ref } from 'vue'

export function useWindowSize() {
  const width = ref(window.innerWidth)
  const height = ref(window.innerHeight)

  function updateSize() {
    width.value = window.innerWidth
    height.value = window.innerHeight
  }

  onMounted(() => {
    window.addEventListener('resize', updateSize)
  })

  onUnmounted(() => {
    window.removeEventListener('resize', updateSize)
  })

  return { width, height }
}

关联知识点:DOM 操作、资源清理、自定义 Hooks


二、Composition API 详解

2.1 组合式函数(Composables)

组合式函数是 Composition API 的核心,用于封装和复用状态逻辑。

核心要点

代码示例

// useFetch.ts
export function useFetch<T>(url: MaybeRef<string>) {
  const data = ref<T | null>(null)
  const error = ref<Error | null>(null)
  const loading = ref(true)

  watch(url, async (newUrl) => {
    loading.value = true
    try {
      const response = await fetch(newUrl)
      if (!response.ok) throw new Error(response.statusText)
      data.value = await response.json()
    } catch (e) {
      error.value = e as Error
    } finally {
      loading.value = false
    }
  }, { immediate: true })

  return { data, error, loading }
}

// 使用
const { data, loading } = useFetch<User>('/api/user')

关联知识点:逻辑复用、响应式编程、自定义 Hooks

2.2 Teleport 和 Suspense

Vue 3 新增的内置组件,解决特定场景问题。

核心要点

代码示例

<!-- Teleport 示例 -->
<template>
  <button @click="showModal = true">打开模态框</button>
  <Teleport to="body">
    <Modal v-if="showModal" @close="showModal = false">
      <p>模态框内容渲染到 body 下</p>
    </Modal>
  </Teleport>
</template>

<!-- Suspense 示例 -->
<template>
  <Suspense>
    <template #default>
      <AsyncComponent />
    </template>
    <template #fallback>
      <div>加载中...</div>
    </template>
  </Suspense>
</template>

关联知识点:DOM 渲染、异步组件、模态框


三、状态管理

3.1 Pinia

Pinia 是 Vue 3 官方推荐的状态管理库,替代了 Vuex。

核心要点

代码示例

// stores/user.ts
import { defineStore } from 'pinia'

export interface User {
  id: number
  name: string
  role: string
}

export const useUserStore = defineStore('user', () => {
  const user = ref<User | null>(null)
  const token = ref<string | null>(null)

  const isLoggedIn = computed(() => !!user.value && !!token.value)
  const userRole = computed(() => user.value?.role ?? 'guest')

  async function login(credentials: { email: string; password: string }) {
    const response = await api.login(credentials)
    user.value = response.user
    token.value = response.token
    localStorage.setItem('token', response.token)
  }

  function logout() {
    user.value = null
    token.value = null
    localStorage.removeItem('token')
  }

  return { user, token, isLoggedIn, userRole, login, logout }
})

关联知识点:状态管理、TypeScript、模块化

3.2 Vuex(遗留项目)

Vuex 是 Vue 2 时代的状态管理方案,新项目推荐使用 Pinia。

核心要点

关联知识点:状态管理、迁移策略


四、Vue Router

4.1 路由基础

Vue Router 是 Vue 官方路由管理器,支持单页应用的路由切换。

核心要点

代码示例

// router/index.ts
import { createRouter, createWebHistory } from 'vue-router'

const routes = [
  {
    path: '/',
    component: () => import('@/views/Home.vue'),
    meta: { requiresAuth: false }
  },
  {
    path: '/dashboard',
    component: () => import('@/views/Dashboard.vue'),
    meta: { requiresAuth: true, roles: ['admin', 'user'] }
  }
]

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

router.beforeEach((to) => {
  const userStore = useUserStore()
  if (to.meta.requiresAuth && !userStore.isLoggedIn) {
    return '/login'
  }
})

export default router

关联知识点:单页应用、权限控制、懒加载


五、前端设计模式在 Vue 中的应用

5.1 Observer(观察者模式)

Vue 的响应式系统本质上是观察者模式的实现。

应用场景

代码示例

// 简单 EventBus
import mitt from 'mitt'
export const emitter = mitt()

// 发布事件
emitter.emit('user-updated', { name: 'New Name' })

// 订阅事件
emitter.on('user-updated', (data) => {
  console.log('User changed:', data)
})

关联知识点:响应式原理、事件系统

5.2 MVVM 模式

Vue 整体架构遵循 MVVM(Model-View-ViewModel)模式。

应用场景

关联知识点:架构模式、数据绑定

5.3 Factory(工厂模式)

应用场景

代码示例

// 动态组件工厂
const componentMap = {
  input: InputField,
  select: SelectField,
  textarea: TextAreaField,
}

function createFieldComponent(type: string, props: any) {
  const Component = componentMap[type]
  if (!Component) throw new Error(`Unknown field type: ${type}`)
  return h(Component, props)
}

关联知识点:动态组件、代码生成

5.4 Strategy(策略模式)

应用场景

代码示例

// 校验策略
const validationStrategies = {
  email: (v: string) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(v),
  phone: (v: string) => /^1[3-9]\d{9}$/.test(v),
  required: (v: string) => v.trim() !== '',
}

function validate(value: string, strategy: string) {
  const fn = validationStrategies[strategy]
  return fn ? fn(value) : true
}

关联知识点:表单校验、算法切换

5.5 Singleton(单例模式)

应用场景

代码示例

// Vue 应用中 router 和 app 都是单例
const router = createRouter({ ... })
const app = createApp(App)
app.use(router)
app.mount('#app')

关联知识点:全局实例、依赖注入

5.6 Decorator(装饰器模式)

应用场景

代码示例

// 组合式函数作为装饰器
function withLoading<T extends (...args: any[]) => Promise<any>>(fn: T) {
  const loading = ref(false)
  const wrapped = async (...args: Parameters<T>) => {
    loading.value = true
    try {
      return await fn(...args)
    } finally {
      loading.value = false
    }
  }
  return { wrapped, loading }
}

关联知识点:高阶函数、指令

5.7 Adapter(适配器模式)

应用场景

代码示例

// API 数据适配器
interface UserDTO {
  user_name: string
  user_age: number
  user_email: string
}

interface User {
  name: string
  age: number
  email: string
}

function adaptUser(dto: UserDTO): User {
  return {
    name: dto.user_name,
    age: dto.user_age,
    email: dto.user_email,
  }
}

关联知识点:数据转换、接口统一

5.8 Proxy(代理模式)

应用场景

关联知识点:响应式原理、性能优化

5.9 Facade(外观模式)

应用场景

代码示例

// API 外观
export const api = {
  user: {
    get: (id: number) => http.get(`/users/${id}`),
    list: (params: QueryParams) => http.get('/users', { params }),
    create: (data: CreateUserDTO) => http.post('/users', data),
    update: (id: number, data: UpdateUserDTO) => http.put(`/users/${id}`, data),
    remove: (id: number) => http.delete(`/users/${id}`),
  }
}

关联知识点:API 设计、封装

5.10 Command(命令模式)

应用场景

关联知识点:撤销重做、操作队列

5.11 Builder(建造者模式)

应用场景

代码示例

// 查询构建器
class QueryBuilder {
  private conditions: string[] = []
  private orderByFields: string[] = []
  private limitValue = 10

  where(condition: string) {
    this.conditions.push(condition)
    return this
  }

  orderBy(field: string) {
    this.orderByFields.push(field)
    return this
  }

  limit(n: number) {
    this.limitValue = n
    return this
  }

  build() {
    return {
      where: this.conditions.join(' AND '),
      orderBy: this.orderByFields.join(', '),
      limit: this.limitValue,
    }
  }
}

const query = new QueryBuilder()
  .where('status = "active"')
  .orderBy('created_at')
  .limit(20)
  .build()

关联知识点:链式调用、复杂对象构建

5.12 Prototype(原型模式)

通过克隆现有对象创建新对象,避免重复初始化。

应用场景

代码示例

// 深拷贝组件配置
function cloneComponentConfig<T extends object>(config: T): T {
  return structuredClone(config) // 现代浏览器原生方法
}

const baseFormConfig = {
  fields: [
    { type: 'input', label: 'Name', required: true },
    { type: 'select', label: 'Role', options: ['admin', 'user'] },
  ],
  submitUrl: '/api/form',
  validateOnBlur: true,
}

// 克隆后微调
const editFormConfig = cloneComponentConfig(baseFormConfig)
editFormConfig.fields.push({ type: 'textarea', label: 'Notes' })

关联知识点:对象克隆、配置管理

5.13 Bridge(桥接模式)

将抽象部分与实现部分分离,使它们可以独立变化。

应用场景

代码示例

// 抽象:图表组件
interface ChartRenderer {
  render(data: ChartData): void
  update(data: ChartData): void
}

// 实现 A:ECharts 渲染器
class EChartsRenderer implements ChartRenderer {
  private chart: echarts.ECharts
  render(data: ChartData) { /* ECharts 初始化 */ }
  update(data: ChartData) { /* ECharts 更新 */ }
}

// 实现 B:Chart.js 渲染器
class ChartJsRenderer implements ChartRenderer {
  private chart: Chart
  render(data: ChartData) { /* Chart.js 初始化 */ }
  update(data: ChartData) { /* Chart.js 更新 */ }
}

// 桥接:根据配置选择实现
const renderer = useECharts ? new EChartsRenderer() : new ChartJsRenderer()

关联知识点:接口抽象、多端适配

5.14 Composite(组合模式)

将对象组合成树形结构,统一处理单个对象和组合对象。

应用场景

代码示例

// 菜单项组件(递归组合)
interface MenuItem {
  label: string
  children?: MenuItem[]
  action?: () => void
}

function renderMenu(items: MenuItem[]) {
  return items.map(item => (
    <div class="menu-item">
      <span @click="item.action">{{ item.label }}</span>
      {item.children && renderMenu(item.children)} // 递归渲染子树
    </div>
  ))
}

关联知识点:递归组件、树形结构

5.15 Flyweight(享元模式)

共享细粒度对象,减少内存占用。

应用场景

代码示例

// 图标享元池
const iconPool = new Map<string, SVGElement>()

function getIcon(name: string): SVGElement {
  if (!iconPool.has(name)) {
    const svg = createSVGIcon(name) // 创建新图标
    iconPool.set(name, svg)
  }
  return iconPool.get(name)!.cloneNode(true) as SVGElement
}

// 使用享元池避免重复创建相同图标
const userIcon = getIcon('user')
const adminIcon = getIcon('user') // 复用同一图标实例

关联知识点:内存优化、对象池

5.16 Iterator(迭代器模式)

提供顺序访问集合元素的方法,不暴露内部结构。

应用场景

代码示例

// 分页迭代器
function* paginatedIterator<T>(fetchFn: (page: number) => Promise<T[]>) {
  let page = 1
  while (true) {
    const items = await fetchFn(page)
    if (items.length === 0) break
    for (const item of items) {
      yield item
    }
    page++
  }
}

// 使用
const userIterator = paginatedIterator((page) => fetch(`/users?page=${page}`))
for await (const user of userIterator) {
  console.log(user.name)
}

关联知识点:生成器、懒加载

5.17 Mediator(中介者模式)

用中介对象封装一系列对象交互,降低耦合度。

应用场景

代码示例

// 表单中介者
class FormMediator {
  private components = new Map<string, any>()
  
  register(name: string, component: any) {
    this.components.set(name, component)
  }
  
  notify(sender: string, event: string) {
    if (sender === 'submitBtn' && event === 'click') {
      const isValid = Array.from(this.components.values())
        .every(c => c.validate?.() ?? true)
      if (isValid) this.components.get('api')?.submit()
    }
    if (sender === 'resetBtn' && event === 'click') {
      this.components.forEach(c => c.reset?.())
    }
  }
}

关联知识点:解耦、事件协调

5.18 Memento(备忘录模式)

在不破坏封装性的前提下,捕获和恢复对象内部状态。

应用场景

代码示例

// 编辑器状态管理
class EditorMemento {
  private history: string[] = []
  private currentIndex = -1
  
  save(state: string) {
    // 删除当前索引之后的历史(新操作覆盖旧撤销栈)
    this.history = this.history.slice(0, this.currentIndex + 1)
    this.history.push(state)
    this.currentIndex++
  }
  
  undo(): string | null {
    if (this.currentIndex > 0) {
      this.currentIndex--
      return this.history[this.currentIndex]
    }
    return null
  }
  
  redo(): string | null {
    if (this.currentIndex < this.history.length - 1) {
      this.currentIndex++
      return this.history[this.currentIndex]
    }
    return null
  }
}

关联知识点:撤销重做、状态快照

5.19 State(状态模式)

允许对象在内部状态改变时改变其行为。

应用场景

代码示例

// 订单状态机
interface OrderState {
  pay(): void
  ship(): void
  complete(): void
  cancel(): void
}

class PendingState implements OrderState {
  pay() { console.log('→ Paid'); /* 切换到 PaidState */ }
  ship() { throw new Error('Cannot ship pending order') }
  complete() { throw new Error('Cannot complete pending order') }
  cancel() { console.log('→ Cancelled'); /* 切换到 CancelledState */ }
}

class PaidState implements OrderState {
  pay() { throw new Error('Already paid') }
  ship() { console.log('→ Shipped'); /* 切换到 ShippedState */ }
  complete() { throw new Error('Cannot ship paid order') }
  cancel() { console.log('→ Refunded'); /* 切换到 RefundedState */ }
}

关联知识点:状态机、业务流

5.20 Interpreter(解释器模式)

给定一个语言,定义它的文法表示,并定义一个解释器。

应用场景

代码示例

// 简单表达式解释器
interface Expression {
  interpret(context: Record<string, any>): boolean
}

class AndExpression implements Expression {
  constructor(private left: Expression, private right: Expression) {}
  interpret(ctx) { return this.left.interpret(ctx) && this.right.interpret(ctx) }
}

class OrExpression implements Expression {
  constructor(private left: Expression, private right: Expression) {}
  interpret(ctx) { return this.left.interpret(ctx) || this.right.interpret(ctx) }
}

class RoleExpression implements Expression {
  constructor(private role: string) {}
  interpret(ctx) { return ctx.roles.includes(this.role) }
}

// 解析 "admin && (read || write)"
const expr = new AndExpression(
  new RoleExpression('admin'),
  new OrExpression(new RoleExpression('read'), new RoleExpression('write'))
)
expr.interpret({ roles: ['admin', 'read'] }) // true

关联知识点:语法解析、规则引擎

5.21 Visitor(访问者模式)

在不改变对象结构的前提下,定义作用于对象各元素的新操作。

应用场景

代码示例

// 组件树访问者
interface ComponentNode {
  type: string
  props?: Record<string, any>
  children?: ComponentNode[]
}

interface Visitor {
  visitComponent(node: ComponentNode): void
  visitChildren(node: ComponentNode): void
}

class ComponentTraverser {
  accept(node: ComponentNode, visitor: Visitor) {
    visitor.visitComponent(node)
    visitor.visitChildren(node)
    node.children?.forEach(child => this.accept(child, visitor))
  }
}

// 具体访问者:统计组件数量
class ComponentCounter implements Visitor {
  count = 0
  visitComponent() { this.count++ }
  visitChildren() {}
}

关联知识点:AST、组件分析


六、前端架构模式

6.1 MVC(Model-View-Controller)

MVC 将应用分为三个部分:模型(数据)、视图(UI)、控制器(业务逻辑)。

核心要点

关联知识点:架构模式、后端 MVC

6.2 MVP(Model-View-Presenter)

MVP 是 MVC 的演进,Presenter 完全隔离 View 和 Model。

核心要点

关联知识点:解耦、测试驱动

6.3 MVVM(Model-View-ViewModel)

Vue 的核心架构模式,通过数据绑定连接 View 和 ViewModel。

核心要点

关联知识点:数据绑定、Vue 架构

6.4 Flux / Redux 模式

单向数据流架构,适合复杂状态管理。

核心要点

关联知识点:状态管理、单向数据流


七、组件通信模式

7.1 Props 和 Emits

父子组件通信的标准方式,单向数据流。

核心要点

关联知识点:单向数据流、组件通信

7.2 Provide/Inject

祖先组件向后代组件传递数据,无需逐层传递。

核心要点

关联知识点:依赖注入、组件库设计

7.3 状态管理

通过 Pinia 等全局状态管理库共享数据。

核心要点

关联知识点:Pinia、全局状态


八、性能优化

7.1 渲染优化

核心要点

关联知识点:虚拟 DOM、缓存策略

7.2 代码分割

核心要点

关联知识点:懒加载、按需加载

7.3 响应式优化

核心要点

关联知识点:Proxy、性能调优


八、工程化

8.1 Vite

Vite 是新一代前端构建工具,Vue 官方推荐。

核心要点

关联知识点:构建工具、开发体验

8.2 TypeScript 集成

Vue 3 使用 TypeScript 重写,类型支持优秀。

核心要点

关联知识点:类型安全、开发效率


九、测试

9.1 单元测试

使用 Vitest + Vue Test Utils 进行组件单元测试。

核心要点

关联知识点:测试策略、质量保证

9.2 E2E 测试

使用 Cypress 或 Playwright 进行端到端测试。

核心要点

关联知识点:自动化测试、CI/CD


十、生态系统

10.1 Nuxt.js

Nuxt 是基于 Vue 的服务端渲染框架。

核心要点

关联知识点:SSR、SEO、全栈框架

10.2 VueUse

VueUse 是 Vue 组合式函数集合。

核心要点

关联知识点:代码复用、工具库

10.3 UI 组件库

关联知识点:组件库、开发效率


十一、与其他框架对比

Vue vs React vs Angular

特性 Vue 3 React 18 Angular
学习曲线
响应式 自动追踪(Proxy) 手动(useState) 自动(Zone.js)
模板 HTML 模板 JSX HTML 模板
状态管理 Pinia Redux/Zustand NgRx
路由 Vue Router React Router Router
类型支持 优秀 优秀 优秀
适用场景 中小型项目、快速开发 大型项目、灵活需求 企业级大型应用

关联知识点:技术选型、框架对比


十二、最佳实践

12.1 代码组织

12.2 性能优化

12.3 安全注意事项

12.4 常见陷阱

关联知识点:代码质量、性能、安全