Vue3 速查表:组合式 API、指令、生命周期一页查清
一份按真实开发场景整理的 Vue3 语法速查,讲清 ref 和 reactive 的区别、computed 和 watch、v-if 和 v-for 指令、setup 语法糖,从 Vue2 迁移和面试都能直接用。
Vue3 速查表:写组件时不用再翻文档
每次新起一个 Vue3 组件,我都会卡在同样几个地方:这个状态该用 ref 还是 reactive,watch 怎么写才会真的触发,v-for 和 v-if 谁先谁后。这些不是难题,是查一次就能解决、却偏偏记不住的东西。所以我把它们整理成了一份能搜的 Vue3 速查表,80 多条真实片段,响应式、生命周期、组件、指令、Pinia 全收。这篇文章把里面最常用的部分讲一遍。
ref 和 reactive 到底有什么区别
这是新人和老手都会反复纠结的一点。说清楚其实只有两条规则。
第一条:ref 什么都能包,基本类型、对象、数组都行;reactive 只对对象、数组、Map、Set 有效,包不了数字和字符串。
第二条按使用场景分:基本类型,以及可能整体替换的对象(比如一次 API 响应、每次导航重新拉的列表),用 ref;按字段原地修改的对象状态(表单、设置、草稿),用 reactive。
reactive 最大的坑是解构。写 const { x } = state 会悄无声息丢掉响应性,这是 Vue3 的头号陷阱。补救办法是 toRefs(state),但拿不准时直接全用 ref,这个坑就绕过去了。
computed 和 watch 别用错
computed 是派生值,有缓存,只在依赖变化时重算,适合"由别的状态算出来的值"。watch 是副作用,适合"状态变了之后要做点什么",比如发请求、写本地存储、手动改另一个值。
watch 不触发是最常见的报错来源,九成出在写法上。watch(obj.x, cb) 传进去的是当时那个解包后的数字,不是被追踪的源,所以永远不响应。正确写法是包成 getter:watch(() => obj.x, cb)。需要深层追踪嵌套对象,再加 { deep: true }。
一段真实的 setup
下面这段把 ref、computed、watch 放在一起,是我写表单时最常重复的结构:
<script setup>
import { ref, computed, watch } from 'vue'
const price = ref(100)
const count = ref(2)
// 派生值,有缓存
const total = computed(() => price.value * count.value)
// 副作用,数量变了打个日志
watch(count, (next, prev) => {
console.log(`数量从 ${prev} 变成 ${next}`)
})
</script>
<template>
<input v-model.number="count" type="number" />
<p>总价:{{ total }}</p>
</template>
注意三点:<script setup> 里没有 this;模板里用 total 不用写 .value,但脚本里访问 ref 必须加 .value;v-model.number 的 .number 修饰符会把输入框的字符串转成数字,省掉手动 parseInt。
指令:v-if、v-for、v-model
v-if 真删真建 DOM 节点,v-show 只切 CSS 的 display,频繁切换用 v-show,很少变化用 v-if。
v-for 必须配 :key,而且不要和 v-if 写在同一个元素上。Vue3 这里有个和 Vue2 反过来的优先级:Vue3 中 v-if 优先级高于 v-for,Vue2 相反。要过滤列表,先用 computed 算出过滤后的数组,再 v-for,既清晰又避开这个坑。
v-model 在自定义组件上的负载从 Vue2 的 value 改成了 modelValue,配套事件是 update:modelValue。它带三个常用修饰符:.lazy 改成 change 时同步,.number 转数字,.trim 去首尾空白。
生命周期与 setup 语法糖
组合式 API 里生命周期是导入的函数:onMounted、onUpdated、onUnmounted,对应 Options API 的 mounted、updated、unmounted。错误边界用 onErrorCaptured,配 KeepAlive 的是 onActivated 和 onDeactivated。
所谓 setup 语法糖就是 <script setup>,它免去了手写 setup() 和 return,顶层定义的变量和导入的组件模板里直接能用。defineProps、defineEmits、defineModel(3.4+)这些编译宏不用 import,直接写。
从 Vue2 迁移与面试
迁移不用大爆炸式重写。Vue3 同一个文件里能混用 Options API 和 Composition API,老组件不动,新组件用 <script setup> 写,改到哪迁到哪。要注意的破坏性改动:v-model 负载改名、filters 移除、允许多根节点。
面试常问的就是这几条:ref 和 reactive 的区别、computed 和 watch 的区别、watch 为什么不触发、组合式 API 相比 Options API 的优势(逻辑能按功能组织成 composable,而不是散在 data、methods、computed 几个桶里)。把这份速查过一遍,这些都能答上来。
如果你也写 React,可以顺手看看 React Hooks 速查表,useState 对 ref、useMemo 对 computed、useEffect 对 watch,两边对照着记反而更牢。
Made by Toolora · Updated 2026-06-13