Vue2 双向绑定,极简版

作者:Administrator 发布时间: 2025-12-15 阅读量:4 评论数:0
// 观察者

class Watcher {

  constructor(obj, key, cb) {

      this.obj = obj;

      this.key = key;

      this.cb = cb;

      Dep.target = this;

      this.value = obj[key]; // 触发 getter

      Dep.target = null;

  }

  update() {

      const newValue = this.obj[this.key];

      if (newValue !== this.value) {

          this.value = newValue;

          this.cb(newValue);

      }

  }

}

// 依赖

class Dep {

  constructor() {

      this.subscribers = [];

  }

  addSub(sub) {

      this.subscribers.push(sub);

  }

  notify() {

      this.subscribers.forEach(sub => sub.update());

  }

}

// 数据劫持 + 收集依赖

function defineReactive(obj, key) {

  let value = obj[key];

  const dep = new Dep();

  Object.defineProperty(obj, key, {

      get() {

          if (Dep.target) {

              dep.addSub(Dep.target);

              console.log(2);

          }

          return value;

      },

      set(newValue) {

          value = newValue;

          dep.notify();

      }

  });

}

// 数据劫持

function observe(obj) {

  if (!obj || typeof obj !== 'object') {

      return;

  }

  Object.keys(obj).forEach(key => {

      defineReactive(obj, key);

  });

}

// Vue 实现

class Vue {

  constructor(options) {

      this.$data = options.data;

      observe(this.$data);

      // 模拟编译和挂载

      const input = document.getElementById('input');

      const text = document.getElementById('text');

      new Watcher(this.$data, 'message', (value) => {

          text.textContent = value;

          console.log(1);

      });

      input.addEventListener('input', (event) => {

          this.$data.message = event.target.value;

      });

      input.value = this.$data.message;

      text.textContent = this.$data.message;

  }

}

// 使用

new Vue({

  data: {

      message: ''

  }

});

评论