Object.defineProperty实现视图数据绑定demo

vue.js 最核心的功能有两个,一个是响应式数据绑定,二是组件系统。
今天讲讲双向数据绑定的实现
vue.js和avalon.js是通过Object.defineProperty实现双向数据绑定的

1、简单用法如下

    var a= {}
    Object.defineProperty(a,"b",{
        value:123
    })
    console.log(a.b);//123

2、具体参数看下面代码、其中有比较关键的setget

var obj = {}; // Creates a new object 创造对象
Object.defineProperty(obj, "hello", {
         get: function () {return sth},
         set: function (val) {/* do sth */}
})
obj.hello // 可以像普通属性一样读取访问器属性
访问器属性的"值"比较特殊,读取或设置访问器属性的值,实际上是调用其内部特性:get和set函数。
obj.hello // 读取属性,就是调用get函数并返回get函数的返回值
obj.hello = "abc" // 为属性赋值,就是调用set函数,赋值其实是传参

好了现在简单讲下如何实现数据视图绑定

极简双向绑定的实现一

    
    

此例实现的效果是:随文本框输入文字的变化,span 中会同步显示相同的文字内容;在js或控制台显式的修改 obj.hello 的值,视图会相应更新。这样就实现了 model => view 以及 view => model 的双向绑定。

![vue实现双向绑定的原理]554AJ.png](http://upload-images.jianshu.io/upload_images/1627906-f6bd2f7554a1e143.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

极简双向绑定的实现二

HTML
    

你好,

JS
var userInfo = {};
Object.defineProperty(userInfo, "nickName", {
    get: function(){
        return document.getElementById('nickName').innerHTML;
    },
    set: function(nick){
        document.getElementById('nickName').innerHTML = nick;
    }
});
Object.defineProperty(userInfo, "introduce", {
    get: function(){
        return document.getElementById('introduce').innerHTML;
    },
    set: function(introduce){
        document.getElementById('introduce').innerHTML = introduce;
    }
})

document.getElementById('btn').onclick = function(){
    userInfo.nickName = "xxx";
    userInfo.introduce = "我是xxx,我来自杭州,..."
}
0
1

三、分解任务
上述示例仅仅是为了说明原理。我们最终要实现的是:


0

1

首先将该任务分成几个子任务:
   1、输入框以及文本节点与 data 中的数据绑定
   2、输入框内容变化时,data 中的数据同步变化。即 view => model 的变化。
   3、data 中的数据变化时,文本节点的内容同步变化。即 model => view 的变化。
要实现任务一,需要对 DOM 进行编译,这里有一个知识点:DocumentFragment

DocumentFragment

DocumentFragment(文档片段)可以看作节点容器,它可以包含多个子节点,当我们将它插入到 DOM 中时,只有它的子节点会插入目标节点,所以把它看作一组节点的容器。使用 DocumentFragment 处理节点,速度和性能远远优于直接操作 DOM。Vue 进行编译时,就是将挂载目标的所有子节点劫持(真的是劫持,通过 append 方法,DOM 中的节点会被自动删除)到 DocumentFragment 中,经过一番处理后,再将 DocumentFragment 整体返回插入挂载目标。

你可能感兴趣的:(Object.defineProperty实现视图数据绑定demo)