编写v1嵌套Web组件

rob*_*cks 10 javascript web-component shadow-dom custom-element

我是webcomponents的新手.由于web组件的v1可用,我从那里开始.我已经在网上阅读了关于他们的各种帖子.我对正确编写它们特别感兴趣.我已经阅读了有关插槽并让它们正常工作的信息,尽管我的努力并未导致按照我的预期方式工作的插槽web组件.

如果我编写了这样的嵌套Web组件,嵌套/开槽web组件中的DOM不会插入父级的插槽中:

<parent-component>
  <child-component slot="child"></child-component>
</parent-component>
Run Code Online (Sandbox Code Playgroud)

这是父webcomponent HTML:

<div id="civ">
  <style>
  </style>
  <slot id="slot1" name="child"></slot>
</div>
Run Code Online (Sandbox Code Playgroud)

由于每个web组件(父组件和子组件)都是独立的,因此我一直在创建它们:

customElements.define('component-name', class extends HTMLElement {
  constructor() {
    super();
    this.shadowRoot = this.attachShadow({mode: 'open'});
    this.shadowRoot.innterHTML = `HTML markup`
  }
})
Run Code Online (Sandbox Code Playgroud)

生成的DOM包括2个阴影根.我试图编写没有阴影dom的子/槽元素,这也不会导致托管孩子的父阴影dom.

那么,构建v1嵌套web组件的正确方法是什么?

Sup*_*arp 9

首先,您必须使用实现Shadow DOM和Custom Elements v1的浏览器.

然后调用attachShadow()将自动将新的Shadow DOM分配给只读属性shadowRoot.

您可以将HTML代码以阴影DOM的innerHTML,但我建议你使用<template>content属性.

然后嵌套很自然:

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 ) )
    }
} )
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

<style>标签中,使用:

  • :host 设置自定义元素的样式,以及
  • ::slotted()设置用<slot>标签插入的元素的样式.