问题
I'm new to webcomponents. Since v1 of webcomponents is available, I'm starting there. I have read various posts around the web about them. I'm particularly interested in composing them correctly. I have read about slots and have them working, although my efforts have not resulted in slotted webcomponents that work the way I expected.
If I have compose nested web components like this, the DOM from the nested/slotted webcomponent does not get inserted in the slot of the parent:
<parent-component>
<child-component slot="child"></child-component>
</parent-component>
And here's the parent webcomponent HTML:
<div id="civ">
<style>
</style>
<slot id="slot1" name="child"></slot>
</div>
Since each webcomponent (parent and child) is written to be independent, I have been creating them with:
customElements.define('component-name', class extends HTMLElement {
constructor() {
super();
this.shadowRoot = this.attachShadow({mode: 'open'});
this.shadowRoot.innterHTML = `HTML markup`
}
})
The resulting DOM includes 2 shadow roots. I have attempted to write child/slotted elements without shadow dom, which also does not result in the parent shadow dom hosting the children.
So, what is the right way to compose v1 nested webcomponents?
回答1:
First, you must use a browser that implements Shadow DOM and Custom Elements v1.
Then the call to attachShadow()
will assign the new Shadow DOM automatically to the read-only property shadowRoot
.
You can append the HTML code to the Shadow DOM's innerHTML
but I'd recommend to use a <template>
's content
property instead.
Then nesting is natural:
customElements.define( 'parent-component', class extends HTMLElement {
constructor() {
super()
this.attachShadow( {mode: 'open'} )
this.shadowRoot.appendChild( parent1.content.cloneNode( true ) )
}
} )
customElements.define( 'child-component', class extends HTMLElement {
constructor() {
super()
var sh = this.attachShadow( {mode: 'open'} )
sh.appendChild( child1.content.cloneNode( true ) )
}
} )
<parent-component>
<child-component slot="child">
<span>Hello</span>
</child-component>
</parent-component>
<template id="parent1">
<style>
:host { background: lightblue ; display: inline-block }
::slotted( [slot=child] ) { background: lightyellow }
</style>
<h4>(parent)</h4>
<p>Slotted child:
<slot name="child"></slot>
</p>
</template>
<template id="child1">
<style>
:host { display: inline-block }
::slotted( span ) { background: pink }
</style>
<h5>(child)</h5>
<span>Nested slot: <slot></slot></span>
</template>
In the <style>
tags, use:
:host
to style the custom element itself, and::slotted()
to style the elements inserted with a<slot>
tag.
来源:https://stackoverflow.com/questions/38976819/composing-v1-nested-web-components