LitElement:根据属性设置样式

时间:2019-11-18 21:02:37

标签: javascript polymer web-component lit-element

我正在使用LitElement构建自定义Web组件,并希望为其提供一个disabled属性。我已经完成了样式设置,但恐怕我正在使用反模式来完成它。我定义了一个类方法,并在render()方法中调用它来设置所需的样式。这是正确的还是有更好的模式?谢谢。

Javascript:

class Button extends LitElement {
    static get properties() {
        return {
            disabled: {type: Boolean},
            isFocused: {type: Boolean},
            isHovered: {type: Boolean},
            isMouseDown: {type: Boolean}
        }
    }

    constructor() {
        super();

        this.disabled = false;
        this.innerButtonText = this.innerHTML;
        this.styles = {};
        this.isFocused = false;
        this.isHovered = false;
        this.isMouseDown = false;
    }

    render() {
        this.setStyles();
        return html`
        <style>@import "https://fonts.googleapis.com/css?family=Montserrat:700";</style>
        <style>@import "https://fonts.googleapis.com/css?family=Montserrat:700";</style>
        <button 
        @focus="${this.onFocus}" 
        @blur="${this.onFocus}" 
        @mouseover="${this.onHover}"
        @mouseout="${this.onHover}"
        @mousedown="${this.onMouseDown}"
        @mouseup="${this.onMouseUp}"
        style=${styleMap(this.styles)}>${this.innerButtonText}</button>
      `
    }

    onHover() {
        this.isHovered = !this.isHovered;
    }

    onMouseDown(event) {
        event.stopPropagation();
        this.isMouseDown = !this.isMouseDown;
    }

    onMouseUp() {
        this.isMouseDown = !this.isMouseDown;
    }

    onFocus() {
           this.isFocused = !this.isFocused
    }

    onClick() {

    }

    setStyles() {
        if (this.disabled)
            this.styles = {
                backgroundColor: 'rgba(51,51,51,0.22)', color: 'rgba(51,51,51,0.66)', fontFamily: 'Montserrat', fontWeight: '700', height: '45px',
                padding: '15px 30px 15px 30px', borderRadius: '5px', border: 'none', boxShadow: '0px 1px 3px #33333338', lineHeight: '1.3', letterSpacing: '1.3px'
            };
        else if (this.isFocused)
            this.styles = {
                backgroundColor: '#2e7d32', color: 'white', fontFamily: 'Montserrat', fontWeight: '700', height: '45px',
                padding: '15px 30px 15px 30px', borderRadius: '5px', border: 'none', boxShadow: '0 0 0 2px white, 0 0 0 4px #84BD00', outline: 'none', lineHeight: '1.3', letterSpacing: '1.3px'
            };
        else if (this.isHovered)
            this.styles = {
                backgroundColor: '#005005', color: 'white', fontFamily: 'Montserrat', fontWeight: '700', height: '45px',
                padding: '15px 30px 15px 30px', borderRadius: '5px', border: 'none', boxShadow: '0px 1px 3px #33333338', lineHeight: '1.3', letterSpacing: '1.3px',
                position: 'relative', top: '+3px', cursor: 'pointer'
            };
        else if (this.isMouseDown)
            this.styles = {
                backgroundColor: '#005005', color: 'white', fontFamily: 'Montserrat', fontWeight: '700', height: '45px',
                padding: '15px 30px 15px 30px', borderRadius: '5px', border: 'none', boxShadow: '0px 1px 3px #33333338', lineHeight: '1.3', letterSpacing: '1.3px',
                position: 'relative', top: '-3px', cursor: 'pointer'
            };
        else {
            this.styles = {
                backgroundColor: '#2e7d32', color: 'white', fontFamily: 'Montserrat', fontWeight: '700', height: '45px',
                padding: '15px 30px 15px 30px', borderRadius: '5px', border: 'none', boxShadow: '0px 1px 3px #33333338', lineHeight: '1.3', letterSpacing: '1.3px'
            };
        }
    }
}

customElements.define('custom-button', Button);

HTML:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<style>@import "https://fonts.googleapis.com/css?family=Montserrat:700";</style>
<script type="module" src="./components/button/button.js"></script>
<body>
<custom-button>Button</custom-button>
<button style="margin: 5px">Button</button>
</body>
</html>

1 个答案:

答案 0 :(得分:3)

首先,将reflect option添加到disabled属性中,以使该属性“反映”该属性的值:

static get properties() {
  return {
    disabled: {
      type: Boolean,
      reflect: true,
    },
  };
}

接下来,创建一个styles static getter来为<button>定义其默认和禁用状态下的样式:

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

// ...

static get styles() {
  return css`
    button {
      background-color: #2e7d32;
      color: white;
      /* ... */
    }

    button[disabled] {
      background-color: rgba(51,51,51,0.22);
      color: rgba(51,51,51,0.66);
    }
  `;
}

最后,在<button>方法中设置disabled的{​​{1}}属性:

render

(您会注意到,我也放弃了render() { return html` <button ?disabled=${this.disabled}><slot></slot></button> `; } 属性,转而使用了更惯用的<slot> element。)

您可以在以下代码段中看到所有这些信息:

innerButtonText
// import { LitElement, css, html } from 'lit-element';
const { LitElement, css, html } = litElement;

class CustomButton extends LitElement {
  static get properties() {
    return {
      disabled: {
        type: Boolean,
        reflect: true,
      }
    };
  }

  constructor() {
    super();
    this.disabled = false;
  }
  
  static get styles() {
    return css`
      button {
        background-color: #2e7d32;
        color: white;
        font-family: Montserrat;
        font-weight: 700;
        height: 45px;
        padding: 15px 30px 15px 30px;
        border-radius: 5px;
        border: none;
        box-shadow: 0px 1px 3px #33333338;
        line-height: 1.3;
        letter-spacing: 1.3px;
      }
        
      button[disabled] {
        background-color: rgba(51,51,51,0.22);
        color: rgba(51,51,51,0.66);
      }
    `;          
  }

  render() {
    return html`
      <button ?disabled=${this.disabled}><slot></slot></button>
    `;
  }
}

customElements.define('custom-button', CustomButton);