在 litElement 中使用 Material Web 组件

zel*_*ite 2 web-component polymer-starter-kit lit-element

我正在尝试使用Polymer 项目中的PWA Starter Kit制作一个小应用程序。

是否可以在我的 LitElement 中使用来自https://material.io/develop/web/components/input-controls/text-field/的 Web 组件?我想使用文本区域。

我尝试过的:

import {html, customElement, LitElement} from "lit-element";
//
import {MDCTextField} from '@material/textfield';

@customElement('text-editor')
export class TextEditor extends LitElement {

    protected render() {
        return html`<div class="mdc-text-field mdc-text-field--textarea">
  <textarea id="textarea" class="mdc-text-field__input" rows="8" cols="40"></textarea>
  <div class="mdc-notched-outline">
    <div class="mdc-notched-outline__leading"></div>
    <div class="mdc-notched-outline__notch">
      <label for="textarea" class="mdc-floating-label">Textarea Label</label>
    </div>
    <div class="mdc-notched-outline__trailing"></div>
  </div>
</div>`
    }

}
Run Code Online (Sandbox Code Playgroud)

但是,因为我不在任何地方使用“MDCTextField”,TypeScript 编译器抱怨“'MDCTextField' 已声明,但它的值从未被读取。”。

我确实在 HTML 中呈现了一个文本区域,但没有应用任何样式。

如何在 LitElement 中重用 MDCTextField Web 组件?

Har*_*til 6

是的,您必须使用 LitElement 的静态样式,它使用可构造样式以及不支持浏览器的回退:

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

import { MDCTextField } from '@material/textfield';

// IMPORTANT: USE WEBPACK RAW-LOADER OR EQUIVALENT
import style from 'raw-loader!@material/textfield/dist/mdc.textfield.css';

@customElement('text-editor')
export class TextEditor extends LitElement {

  static styles = [unsafeCSS(style)];

  private textField?: MDCTextField;

  connectedCallback() {

    super.connectedCallback();

    const elm = this.shadowRoot!.querySelector('.mdc-text-field')! as HTMLElement;

    if (elm && !this.textField) {
      // Element is re-attached to the DOM
      this.makeTextField();
    }
  }

  disconnectedCallback() {
    if (this.textField) {
      this.textField.destroy();
      this.textField = undefined;
    }
  }

  render() {
    return html`
      <div class='mdc-text-field mdc-text-field--textarea'>
        <textarea id='textarea' class='mdc-text-field__input' rows='8' cols='40'></textarea>
        <div class='mdc-notched-outline'>
          <div class='mdc-notched-outline__leading'></div>
          <div class='mdc-notched-outline__notch'>
            <label for='textarea' class='mdc-floating-label'>Textarea Label</label>
          </div>
          <div class='mdc-notched-outline__trailing'></div>
        </div>
    </div>`;
  }

  firstUpdated() {
    // Executed just once
    this.makeTextField();
  }

  private makeTextField() {
    const elm = this.shadowRoot!.querySelector('.mdc-text-field')! as HTMLElement;

    this.textField = new MDCTextField(elm);
  }

}
Run Code Online (Sandbox Code Playgroud)

这些是你需要做的事情:

  1. 使用像 Webpack 或 rollup 这样的打包器将 CSS 文件作为字符串读取。在上面的例子中,我使用了带有raw-loader 的Sebpack 。
  2. MDCTextField使用firstUpdated生命周期事件在第一次呈现组件时初始化。
  3. 随后,一个组件可能会被删除并重新插入到 DOM 中,因此您将需要销毁、清理和重新初始化MDCTextField实例。

  • @zelite,对不起!我忘了在 `connectedCallback` 方法中添加 `super.connectedCallback();`。LitElement 在其超类中执行一次性初始化,因此它是必需的。我更新了片段。 (2认同)