Vue 3 教程

1. Vue 3 简介

Vue (发音为 /vjuː/,类似 view) 是一款用于构建用户界面的 JavaScript 框架。它基于标准 HTML、CSS 和 JavaScript 构建,并提供了一套声明式的、组件化的编程模型,帮助你高效地开发用户界面。

核心特性: 响应式数据绑定、组件化开发、虚拟 DOM 带来的高性能渲染。

一个最基础的 Vue 3 应用示例如下:


import { createApp, ref } from 'vue'

createApp({
  setup() {
    const message = ref('Hello Vue 3!')
    return {
      message
    }
  }
}).mount('#app')
        

2. 组合式 API (Composition API)

组合式 API 是一系列 API 的集合,使我们可以使用函数而不是声明选项的方式书写 Vue 组件。它是一个概括性的术语,涵盖了以下方面的 API:

  • 响应式 API: 例如 ref()reactive(),使我们可以直接创建响应式状态、计算属性和侦听器。
  • 生命周期钩子: 例如 onMounted()onUnmounted(),使我们可以在组件各个生命周期阶段添加逻辑。
  • 依赖注入: 例如 provide()inject(),使我们可以在使用响应式 API 时,利用 Vue 的依赖注入系统。

<script setup>
import { ref, onMounted } from 'vue'

// 响应式状态
const count = ref(0)

// 用来修改状态、触发更新的函数
function increment() {
  count.value++
}

// 生命周期钩子
onMounted(() => {
  console.log(`The initial count is ${count.value}.`)
})
</script>

<template>
  <button @click="increment">Count is: {{ count }}</button>
</template>
        

3. 响应式基础

在组合式 API 中,推荐使用 ref() 函数来声明响应式状态。ref() 接收参数,并将其包裹在一个带有 .value 属性的 ref 对象中返回。

ref vs reactive

除了 ref,Vue 还提供了 reactive(),它使得对象本身具有响应性。

API 适用类型 访问方式
ref() 所有类型 (包括基本类型) 需要 .value
reactive() 仅对象类型 (Object, Array, Map 等) 直接访问属性

import { reactive, ref } from 'vue'

// 使用 ref (基本类型和对象均可)
const count = ref(0)
console.log(count.value) // 0

// 使用 reactive (仅限对象)
const state = reactive({ count: 0 })
console.log(state.count) // 0
        

4. 计算属性 (Computed)

推荐使用计算属性来描述依赖响应式状态的复杂逻辑。它会基于其响应式依赖被缓存。一个计算属性仅会在其响应式依赖更新时才重新计算。


import { reactive, computed } from 'vue'

const author = reactive({
  name: 'John Doe',
  books: [
    'Vue 2 - Advanced Guide',
    'Vue 3 - Basic Guide',
    'Vue 4 - The Mystery'
  ]
})

// 一个计算属性 ref
const publishedBooksMessage = computed(() => {
  return author.books.length > 0 ? 'Yes' : 'No'
})
        

5. 模板指令

指令是带有 v- 前缀的特殊属性。Vue 提供了许多内置指令,常见的有:

  • v-bind (缩写 :):动态绑定一个或多个属性。
  • v-on (缩写 @):监听 DOM 事件。
  • v-if / v-else-if / v-else:条件渲染。
  • v-for:列表渲染。
  • v-model:在表单输入元素或组件上创建双向绑定。

<template>
  <!-- 动态属性绑定 -->
  <div :class="{ active: isActive }"></div>

  <!-- 事件监听 -->
  <button @click="handleClick">Click Me</button>

  <!-- 条件渲染 -->
  <p v-if="seen">Now you see me</p>

  <!-- 列表渲染 -->
  <ul>
    <li v-for="item in items" :key="item.id">
      {{ item.text }}
    </li>
  </ul>

  <!-- 双向绑定 -->
  <input v-model="message" placeholder="edit me" />
</template>