原始 JS 中的双向数据绑定(POC)

2025-06-10

原始 JS 中的双向数据绑定(POC)

作为前端工程师,我们主要使用库和/或框架来开发和维护复杂的 Web 应用,但底层究竟是什么?你会问自己这个问题吗?你不会!?好吧,你应该问!🙃

在这篇文章中,我想将前面的示例扩展为双向数据绑定。🕺

双向数据绑定🤓
如果您不熟悉这个概念,双向数据绑定意味着状态的每个更改都会立即传播到视图(反之亦然)。

查看下面的演示以获得一个简单的示例:

演示

演示

让我们分解一下

我们需要什么来进行双向数据绑定?

  • 在我们的示例 HTML 中是一个视图。
  • 一种状态,用 JavaScript 保存在内存中。

主要特点是:

每次状态改变时,视图都需要更新(单向数据绑定)

但是也

每次视图发生变化时,状态都需要更新

假设我们有一个 HTML视图

    <div class="field">
        <label for="name">Enter your name:</label>
        <input id="name" type="text" name="name"  data-model="name" />
      </div>

      <div class="field">
        <label for="title">Enter your title:</label>
        <input id="title" type="text" name="title" data-model="title" />
      </div>

      <div class="results">
        <h1 data-binding="name"></h1>
        <h2 data-binding="title"></h2>
      </div>
Enter fullscreen mode Exit fullscreen mode

和一个

    const state = {
      name: 'Francesco',
      title: 'Front-end Developer'
    };
Enter fullscreen mode Exit fullscreen mode

我们第一次就可以轻松设置视图:

    document.querySelector('[data-binding="name"]').innerHTML = state.name
    document.querySelector('[data-binding="title"]').innerHTML = state.title
    document.querySelector('[data-model="name"]').value = state.name
    document.querySelector('[data-model="title"]').value = state.title
Enter fullscreen mode Exit fullscreen mode

但是我们想要一些魔法,以便当我们更新状态时:

    state.name = 'Richard'
    state.title = 'Technical Lead'
Enter fullscreen mode Exit fullscreen mode

视图也应该更新

set为了实现这一点,我们可以修改对象属性的默认行为state,这样除了更新状态之外,它还会更新我们的视图

在 JavaScript 中实现这一点的一种方法是使用代理对象

    const createState = (state) => {
      return new Proxy(state, {
        set(target, property, value) {
          target[property] = value; // default set behaviour
          render(); // updates the view every time the state changes
          return true;
    }
      });
    };

    const state = createState({
      name = 'Francesco'
      title = 'Front-end Engineer'
    });
Enter fullscreen mode Exit fullscreen mode

借助代理的强大功能,每次我们更新 时state,该render函数都会被调用。
的一个可能实现render如下:

    const render = () => {
     document.querySelector('[data-binding="name"]').innerHTML = state.name;
     document.querySelector('[data-binding="title"]').innerHTML = state.title;
     document.querySelector('[data-model="name"]').value = state.name;
     document.querySelector('[data-model="title"]').value = state.title;
    };
Enter fullscreen mode Exit fullscreen mode

我们只差最后一点。每次修改view时,state 都应该随之改变。我们可以通过在输入框中添加一个事件监听器来实现这一点:😎

    const listener = (event) => {
      state[event.target.dataset.model] = event.target.value;
    });

   document.querySelector('[data-model="name"]').addEventListener('keyup', listener);  
   document.querySelector('[data-model="title"]').addEventListener('keyup', listener);

Enter fullscreen mode Exit fullscreen mode

!魔术完成了!👨‍💻

更通用的实现(POC)🌟

鏂囩珷鏉ユ簮锛�https://dev.to/phoinixi/two-way-data-binding-in-vanilla-js-poc-4e06
PREV
将任何静态网站转换为 PWA 什么是 PWA? 1. 创建 manifest.json 文件 2. 添加 Service Worker 3. 注册 Service Worker 4. 使网站离线工作 免责声明:通过 Google 获取更多信息 希望你喜欢这篇文章
NEXT
REST、GraphQL 和 gRPC 的自动化样式指南