前置知识: JavaScriptHTML5CSS

Vue 3 语法速查

00:00
1 min Beginner

常用 Vue 3 语法速查表,含使用场景、常见错误,支持搜索和复制

学习指引

前置知识

  • 掌握 HTML、CSS 和 JavaScript 基础
  • 了解前端框架的基本概念

推荐学习顺序

  1. 先学习【模板语法】分组,掌握模板中的数据绑定与指令
  2. 再学习【组合式 API】分组,掌握响应式数据与生命周期

模板语法

Vue 模板是声明式渲染的核心。本组内容涵盖插值、指令和表单绑定,是构建 Vue 组件界面的基础。

插值表达式

<template>
  <p>{{ message }}</p>
  <p>{{ count + 1 }}</p>
  <p>{{ ok ? '是' : '否' }}</p>
</template>
输出: 页面渲染出 message 的值、count+1 的结果和条件表达式的结果
场景: 在模板中输出响应式数据。双花括号内支持 JavaScript 表达式,但不支持语句(如 if/for)。

常见错误

  • 错误: {{ if (ok) { return '是' } }} -- 解决: 使用三元表达式:{{ ok ? '是' : '否' }},或将逻辑移到计算属性中
  • 错误: {{ new Date() }}(在插值中创建对象) -- 解决: 在 setup 中定义计算属性,避免在模板中执行复杂逻辑
进阶: v-once 指令可使插值只渲染一次,后续数据变化不会更新该节点,可用于优化性能。

属性绑定 v-bind

<template>
  <img :src="imageUrl" :alt="imageAlt" />
  <div :class="{ active: isActive, 'text-danger': hasError }"></div>
  <button :disabled="isLoading">提交</button>
</template>
输出: img 标签的 src 和 alt 属性动态绑定,div 的 class 根据条件切换,button 根据 isLoading 状态禁用
场景: 动态绑定 HTML 属性。:src 是 v-bind:src 的简写。支持对象语法绑定 class 和 style,布尔值属性(如 disabled)会根据值的真假自动添加或移除。

常见错误

  • 错误: <img src="{{ imageUrl }}" /> -- 解决: 属性绑定必须使用 v-bind 指令:<img :src="imageUrl" />
  • 错误: <div :class="active: isActive"></div> -- 解决: 对象语法需要花括号::class="{ active: isActive }"
进阶: :class 支持数组语法绑定多个类::class="[baseClass, isActive ? 'active' : '']"。:style 支持数组语法合并多个样式对象。

事件绑定 v-on

<template>
  <button @click="handleClick">点击</button>
  <form @submit.prevent="handleSubmit">提交</form>
  <input @keyup.enter="handleEnter" />
</template>
输出: 点击按钮触发 handleClick,表单提交时阻止默认行为并调用 handleSubmit,回车键触发 handleEnter
场景: 绑定 DOM 事件。@click 是 v-on:click 的简写。支持修饰符:.prevent 阻止默认行为,.stop 阻止冒泡,.enter 等按键修饰符。

常见错误

  • 错误: @click="handleClick()"(需要事件对象时) -- 解决: 不传参数时 Vue 自动传入事件对象:@click="handleClick";如需传参同时获取事件:@click="handleClick($event, arg)"
  • 错误: @click="handleClick"(在组件上监听原生事件) -- 解决: 在 Vue 3 中组件上的事件默认即为自定义事件,需在子组件中通过 emit 触发
进阶: 修饰符可链式使用:@click.stop.prevent。Vue 3 新增了 .exact 修饰符,仅在指定按键组合时触发。

双向绑定 v-model

<template>
  <input v-model="username" placeholder="请输入用户名" />
  <textarea v-model="content"></textarea>
  <select v-model="selected">
    <option value="A">选项A</option>
    <option value="B">选项B</option>
  </select>
</template>
输出: 输入框的值与 username 变量双向同步,选择器的值与 selected 变量双向同步
场景: 在表单元素上创建双向数据绑定。v-model 是 :value 和 @input 的语法糖,自动处理输入和更新。

常见错误

  • 错误: <input :value="username" @input="username = $event.target.value" />(手动实现双向绑定) -- 解决: 直接使用 v-model="username" 即可,它是上述写法的语法糖
  • 错误: <input v-model="username" />(username 是 props) -- 解决: 使用 computed 的 get/set 模式,或通过 emit 通知父组件更新
进阶: v-model 支持修饰符:.lazy 在 change 事件后更新(而非 input),.number 自动转为数字类型,.trim 自动去除首尾空格。

条件渲染 v-if / v-show

<template>
  <div v-if="type === 'A'">类型A</div>
  <div v-else-if="type === 'B'">类型B</div>
  <div v-else>其他类型</div>

  <p v-show="isVisible">可见段落</p>
</template>
输出: 根据 type 的值渲染对应分支,isVisible 为 false 时段落隐藏但仍存在于 DOM
场景: v-if 根据条件决定是否渲染元素(销毁和重建 DOM),v-show 通过 CSS display 属性切换可见性。频繁切换用 v-show,条件很少变化用 v-if。

常见错误

  • 错误: <div v-if="show" /><p v-else>内容</p> -- 解决: v-else 元素必须紧跟在 v-if 元素之后,中间不能有其他元素
  • 错误: 对频繁切换的元素使用 v-if -- 解决: 频繁切换显示/隐藏应使用 v-show,它只切换 CSS display 属性
进阶: v-if 与 template 标签配合可对多个元素进行条件渲染而不产生额外 DOM 节点。v-show 不支持 template 标签。

组合式 API

Vue 3 的核心编程范式。本组内容涵盖响应式数据、计算属性、侦听器和生命周期钩子,是构建复杂逻辑的基础。

ref 响应式引用

import { ref } from 'vue'

const count = ref(0)
const message = ref('你好')

// 修改值
count.value++
message.value = '世界'

// 在模板中自动解包,无需 .value
// <p>{{ count }}</p>
输出: count 的值为 1,message 的值为 '世界'
场景: 创建响应式的基本类型或对象数据。ref 包装后的值通过 .value 访问和修改,在模板中自动解包无需 .value。

常见错误

  • 错误: const count = ref(0) count++(直接修改 ref 对象而非 .value) -- 解决: 必须通过 .value 修改:count.value++
  • 错误: const { value } = ref(0) value++(解构后丢失响应性) -- 解决: 不要解构 ref,始终通过 .value 访问:count.value++
进阶: ref 可包装任意类型值(包括对象),内部对对象类型会自动调用 reactive。shallowRef 只追踪 .value 的替换,不深度追踪对象内部变化。

reactive 响应式对象

import { reactive } from 'vue'

const user = reactive({
  name: '张三',
  age: 25
})

// 直接访问和修改,无需 .value
user.name = '李四'
user.age++
输出: user.name 为 '李四',user.age 为 26
场景: 创建响应式的对象数据。reactive 直接返回响应式代理对象,访问和修改无需 .value。适合管理复杂的对象状态。

常见错误

  • 错误: const { name, age } = reactive({ name: '张三', age: 25 }) -- 解决: 使用 toRefs 保持响应性:const { name, age } = toRefs(user)
  • 错误: let state = reactive({ count: 0 }) state = reactive({ count: 1 }) -- 解决: 使用 ref 包装对象,或直接修改属性:state.count = 1
进阶: reactive 的局限性:不能替换整个对象、不能用于基本类型、解构会丢失响应性。对于简单场景优先使用 ref。

computed 计算属性

import { ref, computed } from 'vue'

const firstName = ref('张')
const lastName = ref('三')

const fullName = computed(() => {
  return firstName.value + lastName.value
})

// 只读,修改 fullName 会警告
输出: fullName 的值为 '张三',且随 firstName 或 lastName 变化自动更新
场景: 定义依赖其他响应式数据的计算值。computed 具有缓存性,只有依赖变化时才重新计算。适合派生状态的场景。

常见错误

  • 错误: const fullName = computed(() => firstName.value + lastName.value) fullName.value = '李四'(修改只读计算属性) -- 解决: 如需可写计算属性,使用 get/set 语法:computed({ get() {...}, set(val) {...} })
  • 错误: computed(() => { sideEffect() })(在计算属性中执行副作用) -- 解决: 计算属性应只做纯计算,副作用放在 watch 或生命周期钩子中
进阶: computed 与方法的区别:computed 有缓存,依赖不变时不会重新计算;方法每次调用都执行。优先使用 computed。

watch 侦听器

import { ref, watch } from 'vue'

const keyword = ref('')

watch(keyword, (newVal, oldVal) => {
  console.log(`搜索关键词从 ${oldVal} 变为 ${newVal}`)
}, { immediate: true })
输出: keyword 变化时输出日志,immediate 选项使回调在创建时立即执行一次
场景: 监听响应式数据的变化并执行副作用。支持 immediate(立即执行)和 deep(深度监听)选项。适合异步操作和副作用逻辑。

常见错误

  • 错误: watch(user, (val) => { ... })(直接监听 reactive 对象的属性) -- 解决: 使用 getter 函数:watch(() => user.age, (val) => { ... }),或监听整个 reactive 对象并加 deep: true
  • 错误: watch(data, handler, { deep: true })(对大对象使用深度监听) -- 解决: 避免对大对象使用深度监听,改为监听具体属性:watch(() => data.specificField, handler)
进阶: watchEffect 是 watch 的简化版,自动追踪回调中使用的响应式依赖,无需指定监听源。适合不关心旧值的场景。

onMounted 生命周期钩子

import { onMounted, onUnmounted } from 'vue'

onMounted(() => {
  console.log('组件已挂载,可访问 DOM')
  startTimer()
})

onUnmounted(() => {
  console.log('组件已卸载,清理资源')
  stopTimer()
})
输出: 组件挂载后输出日志并启动定时器,卸载后清理定时器
场景: 在组件挂载后执行初始化逻辑(如获取数据、操作 DOM、启动定时器),在卸载时清理资源(如清除定时器、取消订阅)。

常见错误

  • 错误: onMounted(() => { ... })(在异步函数中调用) -- 解决: 生命周期钩子必须在 setup 同步阶段调用,不能放在 setTimeout 或 async 函数中
  • 错误: onMounted(() => { startTimer() })(忘记清理) -- 解决: 在 onUnmounted 中清理所有副作用:清除定时器、取消事件监听、断开 WebSocket 连接
进阶: Vue 3 的完整生命周期:onBeforeMount -> onMounted -> onBeforeUpdate -> onUpdated -> onBeforeUnmount -> onUnmounted。还有 onErrorCaptured 用于捕获子组件错误。

知识检测

学习进度

-- 已学文档
--% 知识覆盖率

学习推荐

专注模式