4

10 行代码即可实现响应式 UI

 6 months ago
source link: https://www.fly63.com/article/detial/12655
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

更新日期: 2024-02-21阅读: 16标签: 响应式分享

扫一扫分享

在过去几年中,响应式已成为事实上的标准。所有主要框架都实现了一些响应式模型。其中最大的一个甚至被称为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行代码的响应式

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

65d5579a2f819.jpg

这是一个简单的想法,我们有状态,而我们的 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。

链接: https://www.fly63.com/article/detial/12655


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK