Object.defineProperty实现数据响应

167 阅读1分钟

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
  })