简单双向绑定记录

115 阅读1分钟

传统中通过点击按钮修改data里面的value值但视图不更新 在vue2中使用Object.defineProperty可实现视图更新 核心代码

头部代码与data值

  const body = document.querySelectorAll("body > :not(script)");
    const btn = document.querySelector(".btn");
    const data = {
      value: 1,
      num: "121",
    };
    observer为一个观察者模式
  function module(el, value) {
      let v = data[value];
      Object.defineProperty(data, value, {
        get() {
          return v;
        },
        set(newValue) {
          if (newValue == v) return;
          //更新数据
          observer.emit(newValue, value);
          v = newValue;
        },
      });
    }

观察器

 class Observer {
      constructor() {
        this.event = {};
      }
      on(value, node) {
        if (!this.event[value[1]]) {
          this.event[value[1]] = [];
        }
        this.event[value[1]].push(node);
      }
      emit(newValue, value) {
        // document.querySelector("." + el).innerText = newValue;

        this.event[value].forEach((item) => {
          document.querySelector("." + item).innerText = newValue;
        });
      }
    }
    const observer = new Observer();
通过获取body下的innerText文本匹配{} 模拟vue的 {{}}进行绑定通过正则匹配并绑定到 observer里一个表内
  for (let index = 0; index < body.length; index++) {
      const element = body[index];

      // 使用正则表达式进行匹配
      const regex = /^\{.*\}$/;
      const isMatch = regex.test(element.innerText);
      if (isMatch) {
        const result = element.innerText.replace(/{|}/g, "");

        const arr = result.split(".");
        observer.on(arr, element.className);
      }
    }

   将{}换为指定的值并且进行绑定
    function setText(object) {
      const key = Object.keys(object);
      Object.values(object).forEach((item, index) => {
        item.forEach((el) => {
          document.querySelector("." + el).innerText = data[key[index]];
          module(el, key[index]);
        });
      });
    }
    setText(observer.event);

最终绑定一个btn按钮事件对data.value进行++可修改视图中的值