litelement - 如何根据 属性 或属性值计算样式

litelement - how to compute style based on property or attribute values

我正在遵循 LitElement 指南here,但似乎无法根据其属性计算自定义元素的样式值。

我希望我的元素以下列方式之一编写:

<my-element data="some values" darkmode></my-element>
<my-element data="some values"></my-element>

我想根据是否设置 dardmode 属性来设置元素的背景和文本颜色的样式。

在我的 LitElement class 中,我创建了一个对应的 属性 并对其进行了初始化。但是,在静态样式中,this.darkMode 总是返回 false。我想我在这里遗漏了一些东西但不确定是什么:

class MyElement extends LitElement {

    static get properties() {
        return {
            data:    { type: String },
            darkMode:   { type: Boolean }
        };
    }

    static get styles() {
        const background_color = this.darkMode ? css`#000` : css`#fff` ;
        const text_color = this.darkMode ? css`#fff` : css`#333333`;

        return [
            css`
            :host {
                display: block;
            }
            .data-container {
                font-family: "Roboto",-apple-system,BlinkMacSystemFont,"Segoe UI","Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";
                -webkit-font-smoothing: antialiased;
                -moz-osx-font-smoothing: grayscale;
                text-rendering: optimizeLegibility;
                background-color: ${background_color} !important;
                color: ${text_color} !important;
            }`
       ];

    constructor() {
        super();
        this.data = "";
        this.darkMode = false;
    }

    render() {
        return html`
           <div class="data-container">
               <p>${this.data}</p>
           </div>
        `;
    }
}

customElements.define('my-element', MyElement);

在此代码中:

static get styles() {
  const background_color = this.darkMode ? css`#000` : css`#fff` ;
  // ...

styles是一个静态方法,所以里面的this指的是MyElementclass本身,所以this.darkMode就是darkMode[= MyElement 的 40=] 而不是 MyElement 的任何实例的 darkMode 属性。当然,MyElement.darkMode 始终是 undefined,因此您始终获得“轻”样式。

一种不同且更易于维护的方法是使用 reflect: true 选项将 darkMode 属性“反映”到元素的属性,然后使用 CSS 属性选择器 [dark-mode] 覆盖“浅色”样式,例如:

.data-container {
  background-color: #fff;
  color: #333;
}
:host([dark-mode]) .data-container {
  background-color: #000;
  color: #fff;
}

您可以在下面的代码片段中看到它的工作原理:

const { LitElement, css, html } = litElement;

class MyElement extends LitElement {
  static get properties() {
    return {
      data: { type: String },
      darkMode: {
        type: Boolean,
        reflect: true,
        attribute: 'dark-mode',
      },
    };
  }

  static get styles() {
    return css `
      :host {
        display: block;
      }
      .data-container {
        background-color: #fff;
        color: #333;
      }
      :host([dark-mode]) .data-container {
        background-color: #000;
        color: #fff;
      }
    `;
  }

  constructor() {
    super();
    this.data = "";
    this.darkMode = false;
  }

  render() {
    return html `
      <div class="data-container">
        <p>${this.data}</p>
      </div>
    `;
  }
}

customElements.define('my-element', MyElement);
<script src="https://bundle.run/lit-element@2.2.1"></script>

<my-element data="some dark values" dark-mode></my-element>
<my-element data="some light values"></my-element>