vue双向绑定原理

143 阅读1分钟

Vue.js采用的是数据劫持+发布/订阅模式的方式,通过Object.defineProperty()来劫持各个属性的setter/getter,在数据变动时发布消息给订阅者(Wacther),触发相应的监听回调。

实现一个简单的双向绑定

<div id="app">
    <input type="text" id="txt">
    <p id="show-txt"></p>
</div>
<script>
    var obj = {}
    Object.defineProperty(obj,'txt',{
        get:function(){
            return obj
        },
        set:function(newVal){
            document.getElementById('txt').value = newVal
            document.getElementById('show-txt').innerHtml = newVal
        }
    })
    document.addEventListener('keyup',function(e){
        obj.txt = e.target.value
    })
</script>

Vue内部通过Object.defineProperty方法属性拦截的方式,把data对象里每个数据的读写转化成getter/setter,当数据变化时通知视图更新。

Object的变化侦测

Object.defineProperty(obj,prop,descriptor)

  • obj:要定义属性的对象
  • prop:要定义活修改的属性的名称
  • descriptor:要定义活修改的属性描述符
Object.defineProperty(obj,key,{
    enumerable:true,
    configurable:true,
    get(){
        console.log(`${key}属性被修改了`);
    },
    set(newVal){
        if(val === newVal){
            return
        }
        console.log(`${key}属性被修改了`);
        val = newVal
    }
})

Object.defineProperty()方法会直接在一个对象上定义一个新属性,或者修改一个对象的想有属性,并返回这个对象。