【问题标题】:litelement - how to compute style based on property or attribute valueslitelement - 如何根据属性或属性值计算样式
【发布时间】:2019-08-01 17:44:42
【问题描述】:

我正在关注 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);

【问题讨论】:

    标签: javascript css web-component lit-element


    【解决方案1】:

    在这段代码中:

    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;
    }
    

    你可以在下面的 sn-p 中看到这个工作:

    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>

    【讨论】:

    • 不错的答案,我要补充一点,如果他愿意,他也可以使用 css 变量来实现相同的结果,而无需依赖主机级别的样式
    • 感谢@jordan-running 的解释和示例测试。我是 webcomponent 的新手,仍在学习所有这些。同时,我通过直接在渲染方法的&lt;div&gt; 元素的类名中回显${this.darkmode ? 'dark' : 'light'} 来处理它略有不同。然后我有一个单独的 div 类名,用于样式。从这里跟随指南:lit-element.polymer-project.org/try/style
    猜你喜欢
    • 2013-04-03
    • 1970-01-01
    • 2023-03-14
    • 1970-01-01
    • 2021-08-08
    • 2021-02-10
    • 1970-01-01
    • 1970-01-01
    • 2018-06-15
    相关资源
    最近更新 更多