如何使模板对属性属性的更改做出反应?

问题描述 投票:0回答:1

考虑这个非常基本的计算器(在这里尝试一下):

import {html, css, LitElement} from 'lit';
import {customElement, property} from 'lit/decorators.js';

@customElement('simple-calc')
export class SimpleCalc extends LitElement {
  @property()
  value1 = 3
      
  @property()
  value2 = 0

  render() {
    return html`
        <input type="number"
          .value=${this.value1}
          @change=${(e) => this.value1 = e.target.value}>
        <input type="number"
          .value=${this.value2}
          @change=${(e) => this.value2 = e.target.value}>
        <p>Difference: ${this.value1 - this.value2}</p>`;
  }
}

它按预期工作,只要任一输入的值发生变化,差异就会更新。现在我想做同样的事情,但是

value1
value2
不是
LitElement
的“直接”属性,而是属性的属性,即(在这里尝试):

  @property()
  obj = {value1: 3, value2: 0}

  render() {
    return html`
        <input type="number"
          .value=${this.obj.value1}
          @change=${(e) => this.obj.value1 = e.target.value}>
        <input type="number"
          .value=${this.obj.value2}
          @change=${(e) => this.obj.value2 = e.target.value}>
        <p>Difference: ${this.obj.value1 - this.obj.value2}</p>`;
  }

但在这种情况下,差异不会“实时”更新。我怎样才能做到这一点?

javascript typescript web-component lit
1个回答
0
投票

Lit 中的反应性基于引用相等性,因此改变对象不会像您所看到的那样触发更新。

有几种方法可以解决这个问题:

手动拨打
this.requestUpdate()

这样做可以让 Lit 知道重新渲染。

  @property()
  obj = {value1: 3, value2: 0}

  render() {
    return html`
        <input type="number"
          .value=${this.obj.value1}
          @change=${(e) => {
            this.obj.value1 = e.target.value;
            this.requestUpdate();
          }}>
        <input type="number"
          .value=${this.obj.value2}
          @change=${(e) => {
            this.obj.value2 = e.target.value;
            this.requestUpdate();
          }}>
        <p>Difference: ${this.obj.value1 - this.obj.value2}</p>`;
  }

重新创建对象,使其具有新的引用

这会创建一个新的引用,以便 Lit 可以检测属性更改并重新渲染。

  @property()
  obj = {value1: 3, value2: 0}

  render() {
    return html`
        <input type="number"
          .value=${this.obj.value1}
          @change=${(e) => this.obj = {...this.obj, value1: e.target.value}}>
        <input type="number"
          .value=${this.obj.value2}
          @change=${(e) => this.obj = {...this.obj, value2: e.target.value}}>
        <p>Difference: ${this.obj.value1 - this.obj.value2}</p>`;
  }

immer这样的库可以帮助处理更复杂的对象。

在这里阅读更多相关信息:https://lit.dev/docs/components/properties/#mutating-properties

© www.soinside.com 2019 - 2024. All rights reserved.