您好,欢迎来到宝玛科技网。
搜索
您的当前位置:首页对VUE双向绑定的理解

对VUE双向绑定的理解

来源:宝玛科技网

概括成一句话就是:

视图更新=>数据更新,数据更新=>视图更新

通过Object.defineProperty()来实现数据劫持,这个方法重新定义了对象获取属性值(get)和设置属性值(set)的操作来实现的。

defineProperty的用法

var Book = {}
//var name = '';
//第一个参数:定义属性的对象。
//第二个参数:要定义或修改的属性的名称。
//第三个参数:将被定义或修改的属性描述符。
Object.defineProperty(Book, 'name', {
  //设置值
  set: function (value) {
    name = value;
    console.log('你设置书名叫做:',value);
  },
  //获取值
  get: function () {
    return '《' + name + '》'
  }
});
//赋值调用set
Book.name = 'vue权威指南';  // 你取了一个书名叫做vue权威指南
//取值调用get
console.log(Book.name);  // 《vue权威指南》

与普通obj.name的区别

configurable 是否可配置
enumerable 是否可枚举
writable 是否可修改
value 值

Object.defineProperty(obj, prop, descriptor)中descriptor的取值如下:

  • configurable
    当且仅当该属性的 configurable 键值为 true
    时,该属性的描述符才能够被改变,同时该属性也能从对应的对象上被删除。 默认为 false。
  • enumerable
    当且仅当该属性的enumerable 键值为 true 时,该属性才会出现在对象的枚举属性中。 默认为 false。
    数据描述符还具有以下可选键值:
  • value
    该属性对应的值。可以是任何有效的 JavaScript 值(数值,对象,函数等)。 默认为 undefined。
  • writable
    当且仅当该属性的 writable 键值为 true 时,属性的值,也就是上面的 value,才能被赋值运算符改变。默认为 false。
    存取描述符还具有以下可选键值:
  • get
    属性的 getter 函数,如果没有 getter,则为undefined。当访问该属性时,会调用此函数。执行时不传入任何参数,但是会传入 this对象(由于继承关系,这里的this并不一定是定义该属性的对象)。该函数的返回值会被用作属性的值。 默认为 undefined。
  • set
    属性的 setter 函数,如果没有 setter,则为
    undefined。当属性值被修改时,会调用此函数。该方法接受一个参数(也就是被赋予的新值),会传入赋值时的 this 对象。 默认undefined。
    代码示例:
const obj={};
obj.name='梦醒';

与这样定义是一样的

Object.defineProperty(obj,'name',{
  value: '梦醒',
  writable: true,
  configurable:true,
  enumerable:true,
});

实现简单版vue的过程,主要实现{{}}、v-model和事件指令的功能。

实现mvvm主要包含两个方面,数据变化更新视图,视图变化更新数据。

关键点在于data如何更新view,因为view更新data其实可以通过事件监听即可,比如input标签监听 ‘input’ 事件就可以实现了。所以我们着重来分析下,当数据改变,如何更新视图的。

数据更新视图的重点是如何知道数据变了,只要知道数据变了,那么接下去的事都好处理。如何知道数据变了,其实上文我们已经给出答案了,就是通过Object.defineProperty( )对属性设置一个set函数,当数据改变了就会来触发这个函数,所以我们只要将一些需要更新的方法放在这里面就可以实现data更新view了。

defineProperty的双向绑定

//html
<div></div>
<input type="text">
//js
//类似 vue的data
let obj = {}

/*
*obj      要劫持的对象
*name     要劫持对象的属性
*callback 劫持以后的操作
*/
function watch(obj, name, callback) {
   let value = obj.name
   Object.defineProperty(obj, name, {
       set(msg) {
           // 触发setter给obj赋值
           value = msg
               //执行劫持后的操作
           callback(value)
       },
       get() {
           //返回获取属性值
           return value
       }
   })
}

//
function doSomething(value) {
   document.querySelector('div').innerHTML = value
   document.querySelector('input').value = value
}
//监听input变化 
//可以参考全兼容版:https://segmentfault.com/a/1190000017524278
document.querySelector('input').addEventListener('input', (e)=> {
   obj['msg'] = e.target.value
})

watch(obj, 'msg', doSomething)

总结:
双向数据绑定,主要是通过Object.defineProperty中的set方法和元素的事件监听addEventListener来实现的。

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- baomayou.com 版权所有 赣ICP备2024042794号-6

违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务