繁体   English   中英

如何使用 HTML 节点作为插槽?

[英]How to use HTML node as slot?

我对web-components完全陌生,无法弄清楚哪个部分出了问题。

我正在尝试创建一个包含buttonweb-component ,该按钮应该显示和隐藏p标签。 下面是代码,它工作正常。

class SpecialButton extends HTMLElement {
  constructor() {
    super();
    this.attachShadow({ mode: 'open' });
    this._toShow = false;

    this.shadowRoot.innerHTML = `
    <style>
      p {
        display: none;
      }
    </style>
    <button>Show</button>
    <slot><p>default paragraph!</p></slot>
    `;
  }

  connectedCallback() {
    const button = this.shadowRoot.querySelector('button');
    const p = this.shadowRoot.querySelector('p');
    
    if (this.hasAttribute('toShow')) {
      this._toShow = this.getAttribute('toShow');

      if (this._toShow) {
        button.textContent = 'Hide';
        p.style.display = 'block';
        this._toShow = false;
      } else {
        button.textContent = 'Show';
        p.style.display = 'none';
        this._toShow = true;
      }
    }


    button.addEventListener('click', () => {
      if (this._toShow) {
        button.textContent = 'Hide';
        p.style.display = 'block';
        this._toShow = false;
      } else {
        button.textContent = 'Show';
        p.style.display = 'none';
        this._toShow = true;
      }
    });
  }
}

customElements.define('uc-button', SpecialButton);

如果我不将任何东西传递给uc-button ,它会很好用

<uc-button toShow="true"></uc-button>

我现在面临的问题是我试图从我的html传递一个p作为slot

<uc-button toShow="true"><p>GGGGGGG</p></uc-button>

结果, <p>GGGGGGG</p>似乎总是显示,我不确定是哪一部分出了问题。 我是不是理解错了slot ,只能接受string不能接受HTML Node?

更新我创建了一个可重现的演示 @ https://codesandbox.io/s/inspiring-hill-evgol?file=/index.html

connectedCallback方法中,您将从 shadowRoot 获取“button”和“p”元素。 这些是默认的。 使用组件时传递的那个不在 shadowRoot 中

<uc-button toShow="true"><p>GGGGGGG</p></uc-button>
connectedCallback() {
  const p = this.shadowRoot.querySelector("p");
  // this "p" isn't the one passed with the "GGGGGGG" textContent, but the one with "Default Paragraph"
}

您传递的元素在light DOM中因此您可以查询 light dom:

const p = this.querySelector("p");

然而,在connectedCallback运行时,light DOM 中的元素还没有被“移动”(它们并没有真正移动,只是呈现在自定义元素<slot>所在的位置。因此,它们被称为分布式节点) . 所以此时你不能查询它们。

那么,什么时候才能拿到那些分布式节点呢? 浏览器会告诉你在 shadowRoot onslotchange上触发的事件

您可以监听插槽中的变化,然后应用监听器。

connectedCallback() {
  // Notice that we bind the callback to "this" because otherwise it'll be shadowRoot,
  // and with the code below you would be still querying the shadowRoot.
  this.shadowRoot.addEventListener('slotchange', this.onSlotChange.bind(this));
}

onSlotChange() {
  const p = this.querySelector("p");
  // this is the passed "p"
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM