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()方法会直接在一个对象上定义一个新属性,或者修改一个对象的想有属性,并返回这个对象。