vue实现双向数据绑定是通过Object.defineProperty()方法来实现劫持的 Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象Object.defineProperty()方法解析 Object.defineProperty()方法有三个参数:Object.defineProperty(obj, key, options)
参数功能/作用obj要修改或定义key值的对象key对应obj对象的里面某有已有或要修改的属性options这个参数对象里面有get,set两个函数,用来定义属性值options有两种主要形式:数据描述符和存取描述符 数据描述符是一个具有值的属性,该值可能是可写的,也可能不是可写的 存取描述符是由getter-setter函数对描述的属性 描述符必须是这两种形式之一;不能同时是两者options参数配置: 数据描述符和存取描述符均具有以下可选键值
{ configurable: Boolean, // 当且仅当该属性的 configurable 为 true 时,该属性描述符才能够被改变,同时该属性也能从对应的对象上被删除,默认为 false enumerable: Boolean, // 当且仅当该属性的enumerable为true时,该属性才能够出现在对象的枚举属性中 }数据描述符同时具有以下可选键值
{ value: undefined, // 该属性对应的值。可以是任何有效的 JavaScript 值(数值,对象,函数等)。默认为 undefined writable: Boolean, // 当且仅当该属性的writable为true时,value才能被赋值运算符改变。默认为 false }存取描述符同时具有以下可选键值:默认值:undefined
{ get: fn, // 一个给属性提供 getter 的方法,如果没有 getter 则为 undefined。当访问该属性时,该方法会被执行,方法执行时没有参数传入,但是会传入this对象(由于继承关系,这里的this并不一定是定义该属性的对象),这个方法没有参数 set: fn, // 一个给属性提供 setter 的方法,如果没有 setter 则为 undefined。当属性值修改时,触发执行该方法。该方法有一个参数,就是对应的每次修改的新值 }如果我现在想要让1,输出true,0输出false,怎么办?我们可以通过Object.defineProperty()方法实现
let Test = {} let name = '' Object.defineProperty(Test, 'name', { configurable: true, enumerable: true, set: function (val) { name = val console.log('你输入的值为:' + val) }, get: function () { if (name === 1) { name = true console.log('获取值的时候触发!') return name } else if (name === 0) { name = false console.log('获取值的时候触发!') return name } } })分别测试一下结果:
Test.name = 0 => // 当我们改变对象或者为对象添加一个属性时,触发了set函数:你输入的值为:0 console.log(Test.name) => // false console.log(name) => // false // 通过测试改变Test对象的属性,我们发现不仅Test对象里面改变了,而且name变量也改变了 name = 0 => // 我们发现,我们改变了name变量的值,但是并没有触发set函数,(可以理解为set只能触发对象参数里面的改变) console.log(Test.name) => // false console.log(name) => // false // 通过测试改变了name变量的值,发现兵没有触发set函数,但是Test对象和name变量的值还是跟着改变了,只触发了get函数,相当于获取name值PS:这里是补充的,上面的测试依旧可以试下,但是原理和结论并不是那样的,其实Object.defineProperty()方法可以理解为监听的就是Test这个对象的,name就是添加的或对象已有的一个属性,这就是为什么上面单独改变name属性,并没有触发set函数,当我们改变Test对象的name属性时,set获取新值,并将其重新赋值给name变量,并在get函数里返回,这样就可以实现动态改变Test的name属性值来保持Test.name===name,所以我们只能操作Test.name,如果要操作name,还是要赋值给Test.name,间接操作Texst.name,然后触发后续事件 这里结合vue的双向绑定只能在input,checkbox这些标签上使用,可以理解为这些标签的value的属性值就相当于我们测试的name属性,通过value可以时刻动态监听input等标签value值的变化,然后将这个新value值赋值给对象指定属性,然后就可以触发后续函数。
测试结果: 无论是在input标签里面输入,还是改变Obj.text的值,两者都会同时改变 至此,vue双向数据绑定原理挖坑完毕。
转载于:https://www.cnblogs.com/zjh-study/p/10706996.html
相关资源:vue数据双向绑定的实现与原理解析(核心完整代码)