15.vue2与vue3双向数据绑定的区别

本文介绍了如何在Vue2中使用Object.defineProperty劫持对象属性并实现发布订阅模式,以及Vue3中Proxy的响应式机制。通过对比,展示了两种方法在数据变化时驱动视图更新的过程。
摘要由CSDN通过智能技术生成

vue2:使用Object.defineProperty对象以及对象属性的劫持+发布订阅模式,只要数据发生变化直接通知变化 并驱动视图更新

<input type="text" id="in"/> 输入的值为:<span id="out"></span>
var int = document.getElementById('in');
var out = document.getElementById('out');
// 定义一个对象
const data={name:'peak',age:10}
// 遍历对象 实现对对象的属性进行劫持
Object.keys(data).forEach((key) => {
   Object.defineProperty(data, key, {
     // 当且仅当该属性的enumerable为true时,该属性才能够出现在对象的枚举属性中
     enumerable: true,
     // 当且仅当该属性的 configurable 为 true 时,该属性描述符才能够被改变,同时该属性也能从对应的对象上被删除
     configurable: true, 
     get: ()=>{ // 一个给属性提供 getter 的方法
       console.info(`get ${key}-${val}`)
       return val;
     },
     set: (newVal)=>{ // 一个给属性提供 setter 的方法
       // 当属性值发生变化时我们可以进行额外操作 如调用监听器
       if(newVal === val ){ // 如果未发生变化 不做其他操作
        return;
       } 
       console.log(`触发视图更新函数${newVal}`);
       out.innerHTML = newVal;
     },
   });   
});
int.addEventListener('input', function(e) {
    obj.name = e.target.value;
})
data.age=25 // 触发set方法 

vue3:Vue3.0中的响应式采用了ES6中的Proxy方法。

Proxy 对象用于定义基本操作的自定义行为(如属性查找、赋值、枚举、函数调用等)

基本语法:const p = new Proxy(target, handler)

let obj = {
    a: 1,
    b: 2
}
const proxy = new Proxy(obj, {
    get: function(target, prop, receiver) {
        return prop in target ? target[prop] : 0
    },
    set: function(target, prop, value, receiver) {
        target[prop] = 666
    }
})
console.log(proxy.a) // 1
console.log(proxy.c) // 0
proxy.a = 10
console.log(proxy.a) // 666
obj.b = 10
console.log(proxy.b) // 不是666 而是10 

 

以上代码中obj是我们要代理的目标对象,get,set方法是参数handler的两个属性,具体如下:

  • handler.get()接收三个参数,第一个参数target为代理的目标对象,第二个参数prop是代理的目标对象的属性,第三个参数是Proxy或者继承Proxy的对象,通常是proxy本身。
  • handler.set()接收四个参数,其中三个参数都与get方法相同,唯独多出来一个value表示新的属性值。

上述代码表示当访问proxy的属性时,进行拦截判断,该属性是否是目标对象的属性,如果是那么就将其值返回出来,否则就返回0。

当对proxy上的属性进行重写时,将重写的该属性赋值为666。

用proxy实现一个简易版的数据响应:

<body>
    <h2 id="app"></h2>
  <input id="input" type="text" />
</body>
let app = document.getElementById('app')
let input = document.getElementById('input')
let obj = { // 源数据
  text:'hello world'
}
let proxy = new Proxy(obj, {
  set: function(target, prop, value){ // input事件触发进行劫持,触发update方法
    target[prop] = value
    update(value)
  }
})
function update(value){ // update方法用于同步dom更新
    app.innerHTML = value
    input.value = value
}
input.addEventListener('input',function(e){ // 监听input数据变化,并修改proxy的值
  proxy.text = e.target.value
})
proxy.text = obj.text // 初始化源数据
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值