【Proxy 】

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <input type="text" v-model="content" />
    <input type="text" v-model="title" />
    <input type="text" v-model="title" />
    <h4 v-bind="title">这里也会发生更新</h4>
    <script>
      function View() {
        let proxy = new Proxy(
          {},
          {
            set(obj, property, value) {
              console.log(value);
              document
                .querySelectorAll(`[v-model="${property}"]`)
                .forEach((el) => {
                  el.value = value;
                });
              document
                .querySelectorAll(`[v-bind="${property}"]`)
                .forEach((el) => {
                  el.innerHTML = value;
                });
            },
            get(obj, property) {},
          }
        );
        this.init = function () {
          const els = document.querySelectorAll("[v-model]");
          els.forEach((el) => {
            el.addEventListener("keyup", () => {
              proxy[el.getAttribute("v-model")] = el.value;
            });
          });
        };
      }
      new View().init();
    </script>
  </body>
</html>

详细解释一下这个数据流程:

  1. 初始化阶段:
this.init = function () {
    const els = document.querySelectorAll("[v-model]");  // 获取所有带 v-model 的输入框
    els.forEach((el) => {
        el.addEventListener("keyup", () => {
            // 当输入时,给 proxy 对象设置属性
            proxy[el.getAttribute("v-model")] = el.value;
        });
    });
};
  1. 当用户输入时:
  • 假设用户在 v-model="title" 的输入框输入 "hello"
  • proxy["title"] = "hello" 被执行
  • 这会触发 Proxy 的 set 陷阱
  1. set 陷阱被触发:
set(obj, property, value) {  // property 是 "title", value 是 "hello"
    // 更新所有 v-model="title" 的输入框
    document.querySelectorAll(`[v-model="${property}"]`)
        .forEach((el) => {
            el.value = value;
        });
    // 更新所有 v-bind="title" 的元素
    document.querySelectorAll(`[v-bind="${property}"]`)
        .forEach((el) => {
            el.innerHTML = value;
        });
}

这就实现了:

  • 一个输入框变化
  • 所有相关输入框和绑定元素都更新
  • 这就是 Vue 双向绑定的简单实现原理
posted @ 2025-04-14 22:34  十三山入秋  阅读(31)  评论(1)    收藏  举报