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

2022-05-09 00:00:00 javascript css web-component lit-element

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

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

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

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

在我的LitElement类中,我创建了一个相应的属性并对其进行了初始化。但是,在静态样式中,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引用MyElement类本身,因此this.darkMode是MyElement的darkMode属性,而不是任何MyElement实例的darkMode属性。当然,MyElement.darkMode总是undefined,所以你总是得到"浅"的样式。

另一种更易于维护的方法是使用reflect: true选项将darkMode属性"映射到元素的属性,然后使用css属性选择器[dark-mode]覆盖"light"样式,例如:

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

您可以在下面的代码片段中看到这一点:

数据-lang="js"数据-隐藏="假"数据-控制台="真"数据-巴贝尔="假">
const { LitElement, css, html } = litElement;

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

  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>

相关文章