响应式数据
Vue3 一切自动更新都建立在"响应式数据"之上:数据一变,用到它的界面立刻跟着变。实现响应式有两个主角——ref 与 reactive。理解它们的区别与适用场景,是吃透 Vue3 的关键。
为什么需要响应式
传统 JS 中改一个变量,页面不会自动更新,得手动操作 DOM:
let count = 0
count = 1 // 页面毫无反应,还要自己找元素去改
Vue3 里把数据变成"响应式"后,赋值即触发界面更新,代码只需关注数据本身。
ref:适合所有值
ref 可以包装基本类型与对象,读取、修改都要通过 .value:
<script setup>
import { ref } from 'vue'
const count = ref(0) // 基本类型
const user = ref({ name: '张三' }) // 对象也可以
count.value++ // 修改用 .value
console.log(count.value) // 输出:1
user.value.name = '李四' // 改对象属性先取 .value
console.log(user.value.name) // 输出:李四
</script>
<template>
<p>{{ count }}</p> <!-- 模板中自动解包,无需 .value -->
</template>
reactive:只接受对象
reactive 接收对象/数组并返回深层响应式代理,读写直接点属性即可:
import { reactive } from 'vue'
const state = reactive({
list: [],
keyword: ''
})
state.keyword = 'vue' // 直接赋值
state.list.push('响应式教程') // 嵌套数组同样响应式
console.log(state.keyword) // 输出:vue
效果:模板里引用 state.keyword 的地方会随赋值自动更新。
各自该怎么选
- 基本类型(数字/字符串/布尔)只能用 ref;
- 对象、数组两者皆可:想要显式的 .value 风格用 ref,想少打字用 reactive;
- 需要整体替换对象时 reactive 不方便(直接换引用会丢失响应式),用 ref 更稳妥;
- 组合式函数对外返回数据时习惯用 ref,便于解构后仍保持响应式。
解构 reactive 会丢失响应式
直接解构 reactive 得到的变量只是"快照",不再与源对象联动:
const { keyword } = state
keyword = 'xxx' // 改了它,state.keyword 不会变!
需要保持联动,请用 toRefs 转换:
import { toRefs } from 'vue'
const { keyword } = toRefs(state) // keyword 变成 ref
keyword.value = 'vue-router' // state.keyword 同步变化
小结
一句话总结:基本类型用 ref、对象优先 reactive、解构保持响应式用 toRefs。把这两个 API 用熟,后续学 computed、watch、Pinia 都会事半功倍。