组件编程三
内容纲要
样式覆盖
自定义组件的问题在于样式覆盖:
<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
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。