原生js实现数据双向绑定原理解析

作者 新城 日期 2017-10-25
原生js实现数据双向绑定原理解析

双向数据绑定实现的方式

最近学习vue2.5,再说到mvvm框架之前,首先解释下下什么事双向数据绑定

  • 单项数据绑定

事先把模板写好 然后把模板数据整合到一张html页面上 然后将其插入到文档中 (那会还是刀耕火种的年代)
缺点
一旦模板生成 试图只能通过手动操作dom区实现 即使数据已经发生变化(这里只用户反馈信息)只能手动更新dom 效率很低

  • 双向数据绑定

视图和数据实现同步 用户修改视图中信息或实时同步到modal中 modal中数据的变化 也会实时展示到视图上

优点
无需实时手动更新dom操作
缺点
应用场景有限

(双向数据绑定底层实现)[http://www.jianshu.com/p/e8df6e3f6e34]
1.手动绑定,同时使用dirty check(脏检查)去循环监听。(代表angular js Emberjs)
2.Object.observe ECMAScript7中的新属性 支持性不是很广泛
3.发布者-订阅者模式(backbone.js)
4.前端数据劫持,使用Object.defineProperty ECMAScript5.1(代表Vue js)

  • Object.defineProperty(obj, prop, descriptor)
    obj ,待修改的对象
    prop ,带修改的属性名称
    descriptor ,待修改属性的相关描述
    descriptor 要求传入一个对象,其默认值如下,
1
2
3
4
5
6
7
8
9
/*** @{param} descriptor*/ 参数
{
configurable: false,
enumerable: false,
writable: false,
value: null,
set: undefined,
get: undefined
}

configurable,属性是否可配置。可配置的含义包括:是否可以删除属性( delete ),是否可以修改属性的 writable 、 enumerable 、 configurable 属性。
enumerable,属性是否可枚举。可枚举的含义包括:是否可以通过 for…in 遍历到,是否可以通过 Object.keys() 方法获取属性名称。
writable,属性是否可重写。可重写的含义包括:是否可以对属性进行重新赋值。
value,属性的默认值。
set,属性的重写器(暂且这么叫)。一旦属性被重新赋值,此方法被自动调用。
get,属性的读取器(暂且这么叫)。一旦属性被访问读取,此方法被自动调用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<input type="text" id="aa"/>
<span id="bb">{{hello}}</span>
<script>
var obj = {}; // 声明一个对象
Object.defineProperty(obj,'hello',{ // 在对象上面添加hello属性
set:function(val){ // 置hello属性的数值
document.getElementById('bb').innerHTML = val;
document.getElementById('aa').value = val;
}
});
document.getElementById('aa').onkeyup = function(e){
obj.hello = e.target.value;
};
obj.hello = "";
</script>

模板更新策略
字符串
更新变量
虚拟dom

(vue2 MVVM 核心源码解读)[https://github.com/songhaoreact/vue2-source-code/blob/master/MVVM/README.md]