首页 前端知识 Vue2 、vue3 监听对象的变化

Vue2 、vue3 监听对象的变化

2024-02-29 12:02:12 前端知识 前端哥 664 148 我要收藏

1  响应式原理

vue响应式也叫作数据双向绑定

MVVM模型 (Model-Viem-ViewModel)

  • DOM listeners:实现了页面与数据的绑定,当页面操作数据的时候 DOM 和 Model 也会发生相应的变化
  • Data Bindings:  实现了数据与页面的绑定,当数据发生变化的时候会自动渲染页面

2 vue2 数据监听

2.1  实现原理

vue实现数据响应式,是通过object.defineProperty()对数据劫持侦测数据变化,发布订阅模式进行依赖收集与视图更新。

object.defineProperty()方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。

2.2  object.defineProperty()对数据的监听

const obj = {
  name: "one",
  age: 18
}


Object.keys(obj).forEach(key => {
  let value = obj[key]

  Object.defineProperty(obj, key, {
    get: function() {
      console.log(`监听到obj对象的${key}属性被访问了`)
      return value
    },
    set: function(newValue) {
      console.log(`监听到obj对象的${key}属性被设置值`)
      value = newValue
    }
  })
})

obj.name = "two"
obj.age = 20

console.log(obj.name)   
console.log(obj.age)

obj.height = 1.88

2.3 object.defineProperty()缺陷

1.defineProperty只能监听某个属性,不能对全对象监听 对一个对象的监听需使用foreach、闭包等技术

2. defineproperty不能监听到对象的添加删除属性操作

需要开发者主动调用相应的方法去更新 :Vue.set(),Vue.delete

2.defineproperty不能监听数组的添加删除操作

直接使用索引 index 设置数组项时,不会被vue检测到

vue2.0使用数组重写的方法实现了数组的响应,7个方法分别为

  • push();

  • pop();

  • shift();

  • unshift();

  • splice();

  • sort();

  • reverse()

3 vue3 数据监听

3.1 原理 

Proxy 对象用于创建一个对象的代理,从而实现基本操作的拦截和自定义。之后的操作都是直接对Proxy的操作,而不是原有的对象

const p = new Proxy(target, handler)

target 要使用 Proxy 包装的目标对象(可以是任何类型的对象,包括原生数组,函数,甚至另一个代理)。

handler 一个通常以函数作为属性的对象,各属性中的函数分别定义了在执行各种操作时代理 p 的行为。

handler对象的方法【MDN】(13个捕获器 trap)   

3.2 代码

const obj = {
  name: 'one',
  age: 18,
};

const objProxy = new Proxy(obj, {
  // 获取值时的捕获器
  get: function (target, key) {
    console.log(`监听到对象的${key}属性被访问了`, target);
    return target[key];
  },

  // 设置值时的捕获器
  set: function (target, key, newValue) {
    target[key] = newValue;
    console.log(`监听到对象的${key}属性被设置值`, target);
  },
  // 监听in的捕获器
  has: function (target, key) {
    console.log(`监听到对象的${key}属性in操作`, target);
    return key in target;
  },
  // 监听delete的捕获器
  deleteProperty: function (target, key) {
    delete target[key];
    console.log(`监听到对象的${key}属性delete操作`, target);
  },
});

console.log(objProxy.name);
console.log(objProxy.age);

objProxy.name = 'two';
objProxy.age = 20;

// in操作符
console.log('name' in objProxy);

// delete操作
delete objProxy.name;
console.log(obj.name);
console.log(obj.age);

 执行结果

 

3.3 

转载请注明出处或者链接地址:https://www.qianduange.cn//article/2912.html
标签
评论
会员中心 联系我 留言建议 回顶部
复制成功!