defineProperty可以监听对象属性值的变化,Vue就是利用这个特性实现数据响应的(3.0之后是用proxy)。下面利用这个特性,来实现一个counter。
先上html部分代码:
<div id="counter" computed='count'>
</div>
<button id="increase">+</button>
<button id="decrease">-</button>
然后我们实现一个构造函数Watcher:
function Watch(selector,initState){
this.selector = selector //dom
this.selector.innerHTML = initState
this.logger = [] //值变化记录
this.state = initState //不能直接修改state
return this
}
Watch.prototype.watcher = function(){
Object.defineProperty(this, 'value',{
get:function(){
return this.state
},
set:function(newValue){
console.log(this)
this.logger.push({preValue:this.state,currentValue:newValue})
this.state = newValue
this.selector.innerHTML = this.state
},
enumerable:true,
configurable:true
})
}
使用方法:
// 获取dom
let increase = document.querySelector('#increase')
let decrease = document.querySelector('#decrease')
let counter = document.querySelector('#counter')
//使用Watcher
let watchCounter = new Watch(counter,0)
watchCounter.watcher()
increase.addEventListener('click',function(){
watchCounter.value = watchCounter.state + 1
})
decrease.addEventListener('click',function(){
watchCounter.value = watchCounter.state - 1
})