如何使用 litElement 在另一个组件中获取组件状态更改?

How can I get component state change in another component with litElement?

我开始了一个基于LitElement的项目 有很多组件相互嵌套,假设我们有这样的结构:

根组件是my-app

import { LitElement, html, customElement, query } from 'lit-element';
import './my-form';
import './my-view';
import { MyView } from './my-view';

@customElement('my-app')
export class MyApp extends LitElement {
  @query('my-view') private myView?: MyView;

  private handleCountChange(e: CustomEvent<{ count: number }>) {
    if (!this.myView) throw 'my-view not found!';
    this.myView.count = e.detail.count;
  }

  render() {
    return html`
      <my-form @countChanged=${this.handleCountChange}></my-form>
      <my-view></my-view>
    `;
  }
}

如您所见,我们有两个组件:my-form

import { LitElement, html, customElement, property } from 'lit-element';

@customElement('my-form')
export class MyForm extends LitElement {
  @property({ type: Number }) count: any = 0;

  private updateCount(e: KeyboardEvent) {
    this.count = (<HTMLInputElement>e.target).value;
    this.dispatchEvent(
      new CustomEvent('countChanged', {
        composed: true,
        bubbles: true,
        cancelable: true,
        detail: { count: this.count }
      })
    );
  }

  render() {
    return html`
      <input value=${this.count} @input=${this.updateCount} type="text" />
    `;
  }
}

和我的观点:

import { LitElement, html, customElement, property } from 'lit-element';

@customElement('my-view')
export class MyView extends LitElement {
  @property({ type: Number }) count: number = 0;

  render() {
    return html`
      <p>${this.count}</p>
    `;
  }
}

为了让 属性 countmy-form 变为 my-view 我调度了事件侦听器然后在 my-app 然后在 handleCountChange 我将 count 值分配给 MyView,它作为 class 导入,此外还作为组件导入。

目前,这可行,但我觉得这是一个很长的路要走,尤其是当我有更多的嵌套组件时。我想知道这样做是否有更好的方法。 是否存在类似于 Context API 的东西存在于 react.js 我考虑过使用 redux 但有人不推荐它与 litElemnt 一起使用。 我正在考虑的想法之一是将事件分派到 document 而不是当前组件,但这可能是一种不好的做法!您有什么建议,请告诉我?

你可能已经解决了这个问题,但我可以把我如何处理这个问题发给你。

您需要将状态提升到 my-app 组件。此状态将是单一事实来源,并将 count 值传递给 my-formmy-view 子组件。

my-app 组件中,您可以将 handleCountChange 更改为这样的内容(以防万一,如果您将 count 定义为属性并让 my-app 接收初始值来自属性的值):

 private handleCountChange(e: CustomEvent<{ count: number }>) {
   this.setAttribute('count', count); // If you set `count` as observed attribute, you will not need to call `requestUpdate` method
 }

或者像这样,如果你定义 count 为 class 属性

 private handleCountChange(e: CustomEvent<{ count: number }>) {
   this.count = count;
   this.requestUpdate(); // force to call render method which is necessary in this case
 }

请注意,您还必须将 count 值发送到 my-form 组件。它也可以在没有它的情况下工作,但如果你这样做,你将失去你的状态的单一真实来源,这可能会导致潜在的意外行为。

如果您需要发送示例,请告诉我。