正常运行的demo1
let price = 10
let quantity = 2
let total = 0
let target = () => {
total = price * quantity}target()
}只会一次求值
如果想要多次求值只能加存起来,因此有了storage
加入storage demo2
let price = 10
let quantity = 2
let total = 0
let storage = []
let target = () => {
total = price * quantity
}
let record = () => {
storage.push(target)
}
let replay = () => {
storage.forEach(run => run())
}
record() //先记录一次
target() // 求值 20
// 改变
let price = 20
replay() // total 40这里还是需要手动调用,按照目标,应该是自动调用,自动调用就应该依附于具体的单个属性
加入Dep demo3
class Dep {
add () {
//不需要多次添加
if (target && !storage.includes(target)) {
storage.push(target)
}
}
notify () {
storage.forEach(run => run())
}
}
let dep = new Dep()
let price = 10
let quantity = 2
let total = 0
let storage = []
let target = () => {
total = price * quantity
}
dep.add()
dep.notify()这次依然需要手动调用,只不过比较语义化了,接下来和每个属性绑定
响应式对象 demo4
class Dep {
constructor () {
this.storage = []
}
depend () {
if (target && !this.storage.includes(target)) {
this.storage.push(target)
}
}
notify () {
this.storage.forEach(run => run())
}
}
let data = {
price: 20,
quantity: 2
}
let total = 0, salePrice = 0, target
function Watcher (func) {
target = func
target()
target = null
}
//这里遍历我们需要绑定的data对象
Object.keys(data).forEach(key => {
let intervalValue = data[key]
let dep = new Dep()
Object.defineProperty(data, key, {
get () {
dep.depend()
return intervalValue
},
set (val) {
intervalValue = val
dep.notify()
}
})
})
new Watcher(() => {
total = data.price * data.quantity
})
new Watcher(() => {
salePrice = data.price * 0.5
})这里的watcher更像是对代码做了一层封装,watcher的target是一个函数,每个属性都是一个新的dep,一个watcher对象可能同时属于好几个dep对象,这里price的storage有两个watcher,
quantity只有一个watcher
最后放一个vue的双向绑定部分源码