vue双向数据绑定原理

实现双向绑定的做法

目前几种主流的mvc(vm)框架都实现了单向数据绑定,而我所理解的双向数据绑定无非就是在单向绑定的基础上给可输入元素(input、textare等)添加了change(input)事件,来动态修改model和 view,并没有多高深。所以无需太过介怀是实现的单向或双向绑定。

实现数据绑定的做法有大致如下几种:

发布者-订阅者模式(backbone.js)

一般通过sub,pub的方式实现数据和视图的绑定监听,更新数据方式通常做法是 vm.set(‘property’, value)

脏值检查(angular.js)

通过 setInterval() 定时轮询检测数据变动
事件的触发情况如下:
1.DOM事件,譬如用户输入文本,点击按钮等。
2.XHR响应事件 ( http)3.Location( h t t p ) 3. 浏 览 器 L o c a t i o n 变 更 事 件 ( location )
4.Timer事件( timeout, t i m e o u t , interval )
5.执行 digest() d i g e s t ( ) 或 apply()

数据劫持(vue.js)

采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。属性的赋值操作会触发setter函数的执行,获取操作会触发getter函数的执行

Object.definePriperty()

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

语法
Object.defineProperty(obj, prop, descriptor)

obj
要在其上定义属性的对象。
prop
要定义或修改的属性的名称。
descriptor
将被定义或修改的属性描述符。

返回值

被传递给函数的对象。

在ES6中,由于
Symbol类型的特殊性,用Symbol类型的值来做对象的key与常规的定义或修改不同,而Object.defineProperty
是定义key为Symbol的属性的方法之一。

getter 是一种获得属性值的方法,setter是一种设置属性值的方法。


<input type="text" name="" id="text">
<button id= "btn"></button>
<p id="plabel"></p>
<script type="text/javascript">
    var Inp = document.querySelector("#text");
    var Btn = document.querySelector("#btn");
    var LabelP = document.querySelector("#plabel");
    var data = {};

    Object.defineProperty(data, "name", { 
        configurable: true, 
        //configurable当且仅当该属性的 configurable 为 true 时,该属性描述符才能够被改变,同时该属性也能从对应的对象上被删除。默认为 false。

        //get一个给属性提供 getter 的方法,如果没有 getter 则为 undefined。该方法返回值被用作属性值。默认为 undefined。
        //set 一个给属性提供 setter 的方法,如果没有 setter 则为 undefined。该方法将接受唯一参数,并将该参数的新值分配给该属性。默认为 undefined。
        get: function(){
            console.log('get');
            return Inp.value;
        }, 
        set: function(newValue){ 
            Inp.value = newValue; 
            console.log('set'+'-----'+newValue)
        } 
    }) 
    data.name = "oldInfo"; 
    Inp.onchange = function(){ data.name = data.name; }
    Btn.onclick = function(){ LabelP.innerHTML=data.name}
</script>

Vue

数据劫持
Vue 响应式系统的底层的细节

当你把一个普通的 JavaScript 对象传给 Vue 实例的 data 选项,Vue 将遍历此对象所有的属性,并使用 Object.defineProperty 把这些属性全部转为 getter/setter。通过Object.defineProperty()来劫持data这个大对象的各个属性的setter,getter,然后属性的赋值操作会触发setter函数的执行;取值操作触发getter函数的执行。比如输入框,我输入的时候就触发setter,获取新值我在下面有使用输入框的值得操作时,会执行getter。
这些 getter/setter 对用户来说是不可见的,但是在内部它们让 Vue 追踪依赖,在属性被访问和修改时通知变化。
每个组件实例都有相应的 watcher 实例对象,它会在组件渲染的过程中把属性记录为依赖,之后当依赖项的 setter 被调用时,会通知 watcher 重新计算,从而致使它关联的组件得以更新。

检测变化的注意事项

受现代 JavaScript 的限制 (以及废弃 Object.observe),Vue 不能检测到data对象属性的添加或删除。由于 Vue 会在初始化实例时对属性执行 getter/setter 转化过程,所以属性必须在 data 对象上存在才能让 Vue 转换它,这样才能让它是响应的。

——————暂存

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值