Vue数据双向绑定的原理

#上代码(原生js实现Vue数据双向绑定)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Vue数据双向绑定原理</title>
</head>
<body>
    <p></p>
    <input type="text">

    <script>
        const obj = {
            _temp: ''
        }
        Object.defineProperty(obj,'msg',{
            // obj.msg 获取的时候会触发 get 方法
            get(){
                // console.log('读了')
                // 当你用 obj.msg 获取数据的时候,就会触发 get ,而get 方法里面返回的就是obj._temp,
                // 所以就能实现视图的变化影响到 obj.msg 的变化了
                return this._temp
            },
            // obj.msg 赋值的时候,会触发 set 方法,set 方法里面第一个参数就是等号右边的值
            set(newValue){
                // console.log('写了' + newValue)

                // 每次写入的数据时候,都会把最终的结果给 obj._temp
                obj._temp = newValue

                // #2 M => V
                // 做一个数据影响视图的操作
                oP.innerHTML = newValue
                oInput.value = newValue

            }
        })

        const oP = document.querySelector('p')
        const oInput = document.querySelector('input')

        // #1 V => M
        // 当在 input 框中输入内容会触发事件
        oInput.oninput = function(e){
            // 这是核心 当 inptu 的 value 改变就触发 obj.msg里的 set方法
            obj.msg = e.target.value
        }
    </script>
    
</body>
</html>

Object.defineProperty

它接受三个参数,而且都是必填的

传入参数


  1. 第一个参数:目标对象
  2. 第二个参数:需要定义的属性或方法的名字。
  3. 第三个参数:目标属性所拥有的特性。(descriptor)

前两个参数不多说了,一看代码就懂,主要看第三个参数descriptor,看看有哪些取值

descriptor


  • configurable: 仅当该属性的 configurable 为 true 时,该属性才能够被改变,也能够被删除。默认为 false
  • enumerable: 仅当该属性的 enumerable 为 true 时,该属性才能够出现在对象的枚举属性中。默认为 false
  • value: 该属性对应的值。可以是任何有效的 JavaScript 值(数值,对象,函数等)。默认为 undefined
  • writable: 仅当仅当该属性的writable为 true 时,该属性才能被赋值运算符改变。默认为 false
  • get: 一个给属性提供 getter 的方法,如果没有 getter 则为 undefined。该方法返回值被用作属性值。undefined
  • set: 一个给属性提供 setter 的方法,如果没有 setter 则为 undefined。该方法将接受唯一参数,并将该参数的新值分配给该属性。默认为undefined。

descriptor默认值


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

会默认帮我们把writable,configurable,enumerable。都设上值,而且值还都是false 

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

上面代码和下面是等价的的( 仅限于第一次设置的时候)

configurable


总开关,第一次设置 false 之后,第二次什么设置也不行了

如果第一次不设置它会帮你设置为false

它的默认值为 false

那第二次再设置他会报错

var a= {}
Object.defineProperty(a,"b",{
  configurable:false
})
Object.defineProperty(a,"b",{
  configurable:true
})
//error: Uncaught TypeError: Cannot redefine property: b

writable


false 是只读

var a = {}; 
Object.defineProperty(a, "b", { 
    value : 123,
    writable : false });
console.log(a.b); // 打印 37
a.b = 25; // 没有错误抛出(在严格模式下会抛出,即使之前已经有相同的值)
console.log(a.b); // 打印 37, 赋值不起作用。

enumerable


属性特性 enumerable 定义了对象的属性是否可以在 for…in 循环和 Object.keys() 中被枚举。

var o = {};
Object.defineProperty(o, "a", { value : 1, enumerable:true });
Object.defineProperty(o, "b", { value : 2, enumerable:false });
Object.defineProperty(o, "c", { value : 3 }); // enumerable defaults to false
o.d = 4; // 如果使用直接赋值的方式创建对象的属性,则这个属性的enumerable为true

for (var i in o) {    
  console.log(i);  
}
// 打印 'a' 和 'd' (in undefined order)

Object.keys(o); // ["a", "d"]

o.propertyIsEnumerable('a'); // true
o.propertyIsEnumerable('b'); // false
o.propertyIsEnumerable('c'); // false

参考:https://blog.csdn.net/m0_51022093/article/details/111597001 & https://juejin.cn/post/6844903506743148552

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值