4.1 响应式数据与副作用函数
先弄清「响应式」到底要解决什么问题:一个函数读了数据,数据变了它要能自动重新执行。
一、什么是副作用函数
副作用函数指的是会产生副作用的函数:它的执行会直接或间接影响其他函数的执行。
// 修改了 body 的内容,影响了外部状态 → 副作用
function effect() {
document.body.innerText = 'hello vue3'
}
// 修改全局变量,同样是副作用
let val = 1
function effect2() {
val = 2
}
判断标准不是「有没有
return」,而是执行时是否改变了自身作用域之外的东西。
二、什么是响应式数据
const obj = { text: 'hello world' }
function effect() {
// effect 执行时读取了 obj.text
document.body.innerText = obj.text
}
obj.text = 'hello vue3' // 修改后,希望 effect 自动重新执行
- 如果值变化后副作用函数能自动重新执行,那么对象
obj就是响应式数据; - 上面这个
obj显然不是——obj.text改掉以后effect不会自己跑。
三、实现响应式数据的两个线索
把「自动重新执行」拆开,只需要抓住两个动作:
| 动作 | 时机 | 要做的事 |
|---|---|---|
| 读取(get) | 副作用函数执行时读到 obj.text | 把该副作用函数收集起来 |
| 设置(set) | obj.text 被赋值 | 把收集到的副作用函数取出来执行 |
- 读取 → 依赖收集(记录「谁用了这个数据」);
- 设置 → 派发更新(通知「用过的人」重新执行)。
四、拦截读取与设置的手段
| 时期 | 手段 | 使用者 |
|---|---|---|
| ES2015 之前 | Object.defineProperty | Vue 2 |
| ES2015+ | Proxy(代理对象) | Vue 3 |
本系列后续统一使用
Proxy的get/set拦截器,这也是 Vue 3 的做法。
相关
- 4.2 响应式数据的基本实现:用 Proxy 的 get/set 把「收集 + 触发」真正跑起来