组件编程三

内容纲要

样式覆盖

自定义组件的问题在于样式覆盖:

<style type="text/css">
    button {
      background: #8B008B;
      color: white;
      padding: 2ch 4ch;
      border: 0;
      font-size: 1.5ch;
    }
</style>
<wa-o>
  <button>WaO</button>
</wa-o>
class WaO extends HTMLElement {

  connectedCallback() {
    const button = this.querySelector("button");
    button.addEventListener("click", this.handleClick);
  }

  handleClick(e) {
    alert("WaO");
  }

}

customElements.define('wa-o', WaO);

组件编程三

这里需要组件内样式与全局样式分开,由于标签嵌套,受全局样式影响,组件内样式跟随全局样式。

组件编程三

同样的,如果定义组件内样式:

const template = document.createElement('template');
template.innerHTML = `
<style>
button {
  background: #8B008B;
  color: white;
  padding: 2ch 4ch;
  border: 0;
  font-size: 1.5ch;
}
</style>
<button>WaOooooo</button>`;

组件内样式

这样就无法定义全局样式,在保证性能的情况下需要将attachShadow的mode打开:

const template = document.createElement('template');
template.innerHTML = `
<style>
@import "./wahaha.css";
</style>
<button>WaOooooo</button>`;

//...
connectedCallback() {
    this.attachShadow({mode: 'open'});
    this.shadowRoot.appendChild(template.content.cloneNode(true));
//...
}

但是这样依然会有问题,因为是导入的样式,样式会有加载过程,这段时间内是没有样式只有内容的(称为:FOUC-Flash of Unstyled Content或者FUUC-Flash Un unstyled Component),所以还需要定义行内样式,🤔

当然这也有其他的方案,比如part,不在此讨论范围内。

自定义样式

也可以通过自定义样式,然后var来传递样式。嗯…🤔

不在此讨论范围内,略。

slot

可以使用slot:

<style type="text/css">
    header {
      background: red;
    }

    h2 {
      color: red;
    }
    .module {
      border: 1px solid red;
    }
</style>
<i-header></i-header>

<i-module>
  <h2 slot="header">Indeex Moduleeeeeeeee</h2>
</i-module>
class IHeader extends HTMLElement {
  constructor() {
    super();
    const headerTemplate = document.createElement('template');
    headerTemplate.innerHTML = `
      <style>
        header {
          background: #861d1d;
          color: white;
          padding: 4ch;
        }
      </style>
      <header>
        WaOoooo Indeex Header Navvvvvvvv....
      </header>
    `;
    this.attachShadow({mode: 'open'});
    this.shadowRoot.appendChild(headerTemplate.content.cloneNode(true));
  }

}

class IModule extends HTMLElement {

  constructor() {
    super();

    const moduleTemplate = document.createElement('template');
    moduleTemplate.innerHTML = `
      <style>
        .module {
            min-height: 60vh;
           padding: 4ch;
           background: pink;
        }
      </style>
      <div class="module">
        <slot name="header"></slot>
      </div>
    `;
    this.attachShadow({mode: 'open'});
    this.shadowRoot.appendChild(moduleTemplate.content.cloneNode(true));
  }

}

customElements.define('i-header', IHeader);
customElements.define('i-module', IModule);

通过中转,也可以使用全局样式 预览

其他方式

当然,也可以使用其他方案,比如:

<submit-form>
  #shadow-root
    <x-form exportparts="some-input some-box">
      #shadow-root
        <x-bar exportparts="some-input some-box">
          #shadow-root
            <x-foo exportparts="some-input some-box"></x-foo>
        </x-bar>
    </x-form>
</submit-form>

<x-form></x-form>
<x-bar></x-bar>
:root::part(some-input) { ... }

当然,这也有很多问题,至少开发起来很。。嗯…🤔

code enjoy!😜😜😜

作者:indeex

链接:https://indeex.club

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。


发表评论

您的电子邮箱地址不会被公开。