vue响应式原理剖析
一、什么是响应式?
我们先来看一下响应式意味着什么?我们来看一段代码:
-
m有一个初始化的值,有一段代码使用了这个值;
-
那么在m有一个新的值时,这段代码可以自动重新执行;
let m = 20
console.log(m)
console.log(m * 2)
m = 40
上面的这样一种可以自动响应数据变量的代码机制,我们就称之为是响应式
的。
那么我们再来看一下对象的响应式:
// 对象的响应式
const obj = {
name: "wqx",
age: 18
}
// 修改obj对象
obj.name = "kobe"
obj.age = 20
二、响应式函数设计
首先,执行的代码中可能不止一行代码,所以我们可以将这些代码放到一个函数中:
- 那么我们的问题就变成了,当数据发生变化时,自动去执行某一个函数;
但是有一个问题:在开发中我们是有很多的函数的,我们如何区分一个函数需要响应式,还是不需要响应式呢?
-
很明显,下面的函数中 foo 需要在obj的name发生变化时,重新执行,做出响应;
-
bar函数是一个完全独立于obj的函数,它不需要执行任何响应式的操作;
const obj = {
name: "wqx",
age: 18
}
function foo() {
console.log(obj.name)
console.log(obj.age)
}
function bar() {
console.log(obj.age + 100)
}
三、响应式函数的实现watchFn
但是我们怎么区分呢?
- 这个时候我们封装一个新的函数
watchFn
; - 凡是传入到watchFn的函数,就是需要响应式的;
- 其他默认定义的函数都是不需要响应式的;
const obj = {
name: "why",
age: 18
}
// function foo() {
// console.log("foo:", obj.name)
// console.log("foo", obj.age)
// console.log("foo function")
// }
// function bar() {
// console.log("bar:", obj.name + " hello")
// console.log("bar:", obj.age + 10)
// console.log("bar function")
// }
// 设置一个专门执行响应式函数的一个函数
const reactiveFns = []
function watchFn(fn) {
reactiveFns.push(fn)
fn()
}
watchFn(function foo() {
console.log("foo:", obj.name)
console.log("foo", obj.age)
console.log("foo function")
})
watchFn(function bar() {
console.log("bar:", obj.name + " hello")
console.log("bar:", obj.age + 10)
console.log("bar function")
})
// 修改obj的属性
console.log("name发生变化-----------------------")
obj.nam