vue双向绑定原理的核心
它的实现的核心是通过Object.defineProperty(),对data的每个属性进行了get、set的拦截。
其实只用Object.defineProperty()已经可以实现双向绑定,只是这样做效率非常低。
观察者模式
观察者模式在双向绑定当中是什么角色呢?
观察者模式让双向绑定更有效率
为什么观察者模式让双向绑定更有效率?
观察者模式,它是一对多的一种模式,在vue里面,“一”是改了某一个data数据,“多”是页面上凡是用了这个数据的地方,都更新。这就是页面上的很多“地方”,都观察者这个data,这就是一对多的关系,所以用观察者模式。
Object.defineProperty()
Object.defineProperty()有三个参数:
1.属性所在的对象
2.要操作的属性
3.被操作的属性的特性,参数格式是对象{},一般是两个,
get:读取属性时触发;
set:写入属性时触发;
Object.defineProperty()基本使用代码演示:
<script>
var obj = {}
Object.defineProperty(obj,'property',{
get:function(){
console.log('读取数据时触发了get')
return 'get的返回值'
},
set:function(){
console.log('写入时触发了set')
}
});
// 写入时触发set,属性赋值就是写入
obj.property = 123;
// 读取时触发get
console.log(obj.property);
</script>
这时控制台输出
极简版的双向绑定:实现input标签输入内容与p标签内容同步
<h1>极简版的双向绑定</h1>
<input type="text" id="txt_id"/>
<p id="p_id"></p>
<script>
var obj = {}
Object.defineProperty(obj,'property',{
get:function(){
console.log('读取数据时触发了get')
return 'get的返回值'
},
set:function(inputValue){
// console.log(inputValue)
document.getElementById('txt_id').value=inputValue;
document.getElementById('p_id').innerHTML=inputValue;
}
});
// 光标、焦点在input输入框里,监听keyup事件
document.addEventListener('keyup',function(e){
// console.log(e.target.value)
obj.property = e.target.value;
});
</script>
运行结果:
数据劫持是什么意思?
就是通过Object.defineProperty,去操作数据的get、set
数据劫持: vue.js 则是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。
参考文献:剖析Vue原理&实现双向绑定MVVM