Vue 的"响应式系统"是它最核心的机制之一,它的任务就是:让数据变化时,自动驱动视图更新。你不需要手动操作 DOM,也不用写一堆监听代码,只需要用 Vue 提供的 API 声明你的数据,Vue 就能帮你搞定数据和页面的同步问题。
来看这张简化的响应式流程图👇:
js
响应式系统全景图
┌────────────────────────┐
│ 响应式变量 │
│ ┌──────────────┐ │
│ │ ref() │ <─────┐ ←------ 适合基本类型
│ │ reactive() │ │ ←------ 适合对象/数组
│ └──────────────┘ │
│ ↓ │
│ 自动依赖追踪 │ ←------ Vue 自动记录谁用到了这个数据
│ ↓ │
│ 模板渲染 / watch │ ←------ 页面或副作用函数都能感知变化
│ ↓ │
│ 自动视图更新 │ ←------ 数据一改,界面就更新,0 操作 DOM
└────────────────────────┘
🔧 响应式数据的创建方式(详细解析)
Vue 3 提供了两个核心 API 来创建响应式状态:
✅ref():用于基本类型(字符串、数字、布尔值等)
js
import { ref } from 'vue'
// 创建一个响应式的基本类型变量 count,初始值为 0
const count = ref(0)
// 修改 count 的值时,要使用 .value 访问
count.value++
🧠 ref 特点:
- ref() 会将原始值(比如数字)包裹成一个对象,结构类似于:
{ value: 0 }
; - 所有对这个值的读取和修改,都必须通过
.value
属性; - 这是 Vue 通过
包一层
的方式让原始类型变得可以追踪变化; - 在模板中使用时,Vue 会帮你自动解包 ,所以可以直接用·
{{ count }}
而不用{{ count.value }}
; - 非常适合处理 表单字段值 、布尔开关 、计数器变量 等基本数据。
❓为什么不能直接用普通变量?
因为普通变量不是响应式的,Vue 没法知道它什么时候变了。用 ref 包装后,Vue 就能在 .value 变化时触发更新。
✅reactive():用于对象类型(对象、数组、Map、Set 等)
js
import { reactive } from 'vue'
// 创建一个响应式的对象 user
const user = reactive({
name: 'Tom',
age: 25
})
// 修改对象属性时,可以直接使用点语法,无需 .value
user.age++ // 页面会自动感知更新
🧠 reactive 特点:
reactive()
是基于 ES6 的 Proxy 实现的,它会对对象的所有属性做拦截
;- 当你读取
user.name
,Vue
内部会记录这个操作; - 当你修改
user.age
,Vue
会通知相关的依赖去更新视图; - 不用
.value
,写起来更像我们平时写 JavaScript; - 非常适合管理结构性的数据,比如:用户信息、表单数据、列表、配置对象等。
⚠️ ref vs reactive 区别与选择
特性 | ref() | reactive() |
---|---|---|
适用类型 | 基本类型(string、number 等) | 引用类型(对象、数组、Map 等) |
是否使用 .value | ✅ 需要(模板中可省略) | ❌ 不需要 |
内部原理 | 包装成 { value: 原始值 } | 使用 Proxy 做对象劫持 |
使用场景 | 表单输入、单个状态值 | 结构化数据(如 user、settings) |
🔚 总结一句话
在 Vue 中,只要你用 ref()
或 reactive()
声明了变量,Vue 就能帮你自动追踪依赖、检测变化,并更新视图,彻底解放你的手动 DOM 操作!
❤️ 如果你觉得有收获...
如果这篇文章让你对 Vue 的响应式系统有了更清晰的认识,欢迎点赞 👍、收藏 ⭐、评论交流 💬 或转发给朋友 📣!喜欢我的内容的话,也欢迎点击关注我!你的一次点赞和关注,是我持续创作最大的动力 ❤️