美文网首页
1.3 对象的数据劫持

1.3 对象的数据劫持

作者: 星星的成长之路 | 来源:发表于2020-10-29 19:28 被阅读0次
observe(data)响应式原理;

数据劫持方法

  • 对对象数据进行数据劫持
  • 把data中的数据都使用Object.defineProperty重新定义 (es5方法)
  • Object.defineProperty 不能兼容ie8 及以下 vue2 无法兼容ie8版本
  • walk()
  • new Observer(data) 用来观测数据
  • defineReactive(data,key,data[key]); // 定义响应式数据

如果data不是对象或者是null,直接返回;

export function isObject(data) {
  return typeof data === 'object' && data !== null;
}
注意:
  • defineReactive时,如果value是{},需要遍历劫持{}里面的数据
  • set的时候,改变的数据是{},需要再把里面的数据也劫持一遍;
// 把data中的数据 都使用Object.defineProperty重新定义 es5
// Object.defineProperty 不能兼容ie8 及以下 vue2 无法兼容ie8版本
import { isObject } from '../util/index';
class Observer {
  constructor(value) {
    // vue如果数据的层次过多 需要递归的去解析对象中的属性,依次增加set和get方法
    this.walk(value); // 对对象进行观测
  }

  walk(data) {
    let keys = Object.keys(data); // [name,age,address]
    keys.forEach((key) => {
      defineReactive(data, key, data[key]);
    });
  }
}

// 定义响应式数据
function defineReactive(data, key, value) {
  observe(value); // 递归实现深度检测,如果value是{},对子元素进行数据劫持
  Object.defineProperty(data, key, {
    configurable: true,
    enumerable: false,
    get() { //获取值的时候做一些操作
      return value;
    },
    set(newValue) { // 也可以做一些操作
      if (newValue === value) return;
      observe(newValue); // 继续劫持用户设置的值,因为有可能用户设置的值是一个对象
      value = newValue;
    }
  });
}

export function observe(data) {
  let isObj = isObject(data);
  if (!isObj) return;
  return new Observer(data); // 用来观测数据
}

相关文章

网友评论

      本文标题:1.3 对象的数据劫持

      本文链接:https://www.haomeiwen.com/subject/uaeqvktx.html