Vue2.x响应式原理

84 阅读1分钟

简单实现

未添加Watcher和依赖Dep vue2.0响应式原理讲解哔哩哔哩bilibili

// 克隆Array原型并劫持其中的方法
const myArrayPrototype = Array.prototype;
const myProto = Object.create(myArrayPrototype);

const myArrayMethods = ['push', 'pop', 'shift', 'unshift'];
myArrayMethods.forEach((item) => {
  myProto[item] = function () {
    renderView();
    myArrayPrototype[item].call(this, ...arguments);
  };
});

// 视图更新的操作
function renderView() {
  console.log('视图更新');
}

// 全局监视器Observer
function observer(target) {
  // target为基础数据类型 number string boolean
  if (typeof target !== 'object' || target === null) {
    return target;
  }
    
  // target为数组  
  if (Array.isArray(target)) {
    target.__proto__ = myProto;
  }

  // 循环遍历对象中的所有属性
  Object.keys(target).forEach((key) => {
    render(target, key, target[key]);
  });
}

// 渲染函数
function render(target, key, value) {
  observer(value);

  // 劫持对象中的属性
  Object.defineProperty(target, key, {
    get() {
      return value;
    },
    set(newVal) {
      observer(value);
      renderView();
      value = newVal;
    },
  });
}

var obj = {
  name: 'liuchuanzheng',
  age: 18,
  hobby: ['basketball', 'lol', 'live'],
  info: {
    job: 'dev-engineer',
    company: 'bank',
  },
};

observer(obj);

// obj.name = 'angang';
obj.hobby.push('develop');