0

我正在尝试学习 StencilJs 并创建了一个像这样的“可编辑文本”组件。

import { Component, h, Prop, Element } from '@stencil/core';

@Component({
  tag: 'app-input',
  styleUrl: 'app-input.scss',
  shadow: true,
})
export class AppInput {
  @Element() el: HTMLElement;
  @Prop() editMode = false;
  @Prop() value: string;

  private textInput: HTMLInputElement;
  private label: HTMLDivElement;

  componentDidUpdate() {
    if (this.textInput) {
      this.textInput.focus();
    } else {
      this.label.focus();
    }
  }

  eventHandler(event: KeyboardEvent | FocusEvent): void {
    if (event instanceof KeyboardEvent) {
      if (this.editMode) {
        if (event.code === 'Enter') {
          this.value = (event.target as HTMLInputElement).value;
          this.editMode = false;
        } else if (event.code === 'Escape') {
          this.editMode = false;
        }
      } else {
        if (['Space', 'Enter'].some(key => key === event.code)) {
          this.editMode = true;
        }
      }
    } else if (event instanceof FocusEvent) {
      this.editMode = false;
    }
  }

  render() {
    if (this.editMode) {
      return (
        <div>
          <input
            type="text"
            ref={el => this.textInput = el as HTMLInputElement}
            value={ this.value }
            onKeyDown={(event) => this.eventHandler(event)}
            onBlur={(event) => this.eventHandler(event)}></input>
        </div>
      )
    } else {
      return (
        <div
          tabindex="0"
          ref={el => this.label = el as HTMLDivElement}
          onKeyDown={(event) => this.eventHandler(event)}
          onClick={() => this.editMode = true} >{ this.value }</div>
      );

    }
  }
}

问题是,如果父组件更新,那么它也会更新并componentDidUpdate运行,在不应该的时候设置焦点。有没有一种方法可以告诉(可能通过自定义装饰器)componentDidUpdate 仅在从该组件中触发更新时才运行?或者还有其他方法可以解决吗?

4

0 回答 0