原生Web Components中获取默认插槽子元素的最优方法
获取Web组件默认插槽的子元素
你当前用this.children会拿到组件下所有子元素,包括指定了other插槽的元素。要只获取默认插槽的元素,有两种实用方法:
方法1:用插槽内置的assignedElements()方法(推荐)
Web Components的<slot>元素自带assignedElements()方法,能直接获取分配给该插槽的元素。默认插槽可以通过shadowRoot选中,再调用这个方法:
修改后的JS代码:
customElements.define('my-element', class extends HTMLElement { constructor() { super(); this.attachShadow({ mode: "open" }); const template = document.getElementById("TEMPLATE"); this.shadowRoot.appendChild(template.content.cloneNode(true)); } connectedCallback() { setTimeout( ()=> { // 选中shadow DOM里的默认插槽(不带name属性的slot) const defaultSlot = this.shadowRoot.querySelector('slot:not([name])'); // 获取分配给该插槽的所有元素,flatten: true会展开嵌套插槽的内容 const defaultSlotElements = defaultSlot.assignedElements({ flatten: true }); console.log(defaultSlotElements); }, 100); } });
这个方法最准确,哪怕元素是通过嵌套插槽分配到默认插槽的,也能正确获取。如果不需要展开嵌套插槽,去掉{ flatten: true }参数即可。
方法2:直接筛选组件子元素
如果不想操作shadow DOM,也可以过滤组件本身的子元素,排除带有slot属性的元素:
修改后的JS代码:
customElements.define('my-element', class extends HTMLElement { constructor() { super(); this.attachShadow({ mode: "open" }); const template = document.getElementById("TEMPLATE"); this.shadowRoot.appendChild(template.content.cloneNode(true)); } connectedCallback() { setTimeout( ()=> { // 把children转成数组后过滤掉带slot属性的元素 const defaultSlotElements = Array.from(this.children).filter(el => !el.hasAttribute('slot')); console.log(defaultSlotElements); }, 100); } });
这个方法更简单,但只适用于直接子元素没有指定slot的场景,没法处理嵌套插槽的情况。
内容的提问来源于stack exchange,提问作者run_the_race
相关产品推荐
相关产品推荐

