标准答案
- ref 返回一个带 value 的响应式引用,适合 string、number、boolean,也适合需要整体替换的对象或数组。
- reactive 返回一个响应式代理对象,适合组织多个相关字段,例如表单状态、筛选条件、分页参数。
- 直接解构 reactive 对象的普通属性会丢失响应式连接,因为解构出来的是当前值,不再经过原代理对象读取。
- toRef 可以把 reactive 对象上的某个属性转成 ref,toRefs 可以把对象每个属性都转成 ref,常用于组合式函数返回对象或解构 props / state。
- 模板里 ref 会自动解包,脚本里要通过 .value 读写。reactive 对象不能直接整体替换,否则原来的响应式引用会断开。
题目解析
选择 ref 还是 reactive,不要只看值是不是对象。更实用的判断是:这个状态是否经常整体替换,是否需要解构传递,是否和其它字段形成一个状态组。
reactive 的代理身份很重要。只要绕开代理读取或替换掉代理引用,依赖追踪就容易断。
toRef / toRefs 的价值是保留“这个字段来自原响应式对象”的连接,而不是复制一份值。
代码示例
这个例子展示 reactive 解构丢失响应式,以及用 toRefs 保留连接。
Vue
<script setup lang="ts">
import { reactive, ref, toRefs } from 'vue'
const keyword = ref('')
const filters = reactive({
status: 'active',
page: 1
})
// const { status } = filters
// status 是普通字符串,后续不会跟着 filters.status 更新
const { status, page } = toRefs(filters)
function reset() {
keyword.value = ''
status.value = 'active'
page.value = 1
}
</script>常见误区
- 在脚本里忘记 ref 需要 .value。
- 直接解构 reactive 对象后继续期待解构变量保持响应式。
- 把 reactive 对象整体重新赋值,导致其它地方持有的代理引用不再更新。