首页 小组 问答 话题 好文 素材 用户 唠叨 我的社区

[教程]10 行代码即可实现响应式 UI

小蜗锅Lv.1普通用户
2024-10-17 17:40:43
0
5

在过去几年中,响应式已成为事实上的标准。所有主要框架都实现了一些响应式模型。其中最大的一个甚至被称为react。在本文中,我们将了解如何仅使用几行JavaScript编写简单的响应式UI 。

代理

当谈论响应式 UI 时,我们通常指的是当数据发生变化时自动更新的界面。这种方法变得流行,因为它使开发更容易理解和维护。真相只有一个来源,我们只关心更新它,而不考虑实际的 UI 更新。

我们可以使用一个本机浏览器 api 来实现该响应式。这是代理对象。

Proxy 对象使您能够为另一个对象创建代理,该代理可以拦截并重新定义该对象的基本操作。

这意味着我们可以在设置或获取代理对象的属性时注入代码。这是一个简单的例子:

const target = {
  name: "Foo"
};
const handler = {
  get(target, prop, receiver) {
    return "Proxied: " + target[prop];
  },
};
const proxy = new Proxy(target, handler);
console.log(proxy.name); // Proxied: Foo

该proxy常数几乎与我们原来的常数相同target。它也包含该name属性,但Foo它的值不是 ,而是Proxied: Foo。

连同get,我们还有一个set方法。因此,我们可以执行以下操作:

const target = {
  name: "Foo"
};
const handler = {
  get(target, prop, receiver) {
    return "Proxied: " + target[prop];
  },
  set(obj, prop, value) {
    obj[prop] = 'Bar';
  }
};
const proxy = new Proxy(target, handler);
console.log(proxy.name); // Proxied: Foo
proxy.name = 'A new name value';
console.log(proxy.name); // Proxied: Bar

请注意,即使我们在最后获得Proxied:Bar时将name的值设置为“新名称值”。这是因为setter获取控制权,并将Bar指定为一个值。稍后,我们返回前缀为Proxied:Bar,因为我们有一个自定义getter。

现在,让我们使用 setter 来制作响应式 UI。

10行代码的响应式

我们大多数人现在使用的反应式模型也可以定义为单向数据流。


这是一个简单的想法,我们有状态,而我们的 UI 是它的函数。然后,每次用户交互都会导致状态更改,并且渲染会自动发生。如果我们要改变界面,我们不会去dom而是改变状态。这就是我们想要在这里实现的响应式。使用Proxy API,我们只需十行代码即可完成:

function createReactivity(initialState, onUpdate) {
  const proxy = new Proxy(initialState, {
    set(obj, prop, value) {
      obj[prop] = value
      onUpdate.call(proxy);
    }
  });
  onUpdate.call(proxy);
  return proxy;
}

它createReactivity接受我们的初始状态对象和一个回调函数,每当数据更新时就会触发该回调函数。

实际的例子是这样的:

<div id="container"></div>
<input autofocus />
<script>
  function createReactivity(initialState, onUpdate) {
    const proxy = new Proxy(initialState, {
      set(obj, prop, value) {
        obj[prop] = value
        onUpdate.call(proxy);
      }
    });
    onUpdate.call(proxy);
    return proxy;
  }
  const state = createReactivity({ name: 'Krasimir' }, function () {
    document.querySelector('#container').innerhtml = `
      <h1>Hello, ${this.name}</h1>
    `;
  });
  const input = document.querySelector('input');
  input.addEventListener('input', e => state.name = e.target.value);
  input.value = state.name;
</script>

每当我们更改输入字段的值时,我们都会更新name代理对象的属性。这会导致调用 setter 并触发回调onUpdate,从而将新的 HTML 应用于元素#container。

小蜗锅
小蜗锅

5 天前

签名 : 拿人手短,js方面的不懂问我,为了100块钱的赞助豁出去了。   5       0
评论
站长交流