Web 组件:如何与孩子一起工作? [英] Web components: How to work with children?

查看:31
本文介绍了Web 组件:如何与孩子一起工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在尝试使用 StencilJS 创建一些 Web 组件.

现在我知道有 <slot/> 和命名插槽以及所有这些东西.来自 React,我猜 slot 类似于 React 中的 children.你可以在 React 中使用 children 做很多事情.我经常做的事情:

  1. 检查是否有儿童提供
  2. 迭代子级以对每个子级执行某些操作(例如,将其包装在带有类的 div 中等)

你会如何使用 slot/web components/stencilJS 来做到这一点?

我可以使用

在 Stencil 中获取我的 Web 组件的宿主元素

@Element() hostElement: HTMLElement;

我像这样使用我的组件

<按钮>1</按钮><按钮>2</按钮><按钮>3</按钮></my-custom-component>

我想渲染类似的东西

render() {返回 slottedChildren ?<span>无元素</span>:<ul class="my-custom-component">slottedChildren.map(child => <li class="my-custom-element>{child}</li>)</ul>;}

亲切的问候

解决方案

使用插槽不需要在渲染函数中放置条件.您可以将 no children 元素(在您的示例中为 span)放在 slot 元素中,如果没有为 slot 提供子项,它将退回到它.例如:

render() {返回 (<div><slot><span>没有元素</span></slot>

);}

回答你写的评论——你可以做这样的事情,但需要一些编码而不是开箱即用.每个插槽元素都有一个 assignedNodes 函数.使用这些知识和对 Stencil 组件生命周期的理解,您可以执行以下操作:

从'@stencil/core'导入{组件、元素、状态};@成分({标签: '槽元素',styleUrl: 'slotted-element.css',阴影:真实})导出类 SlottedElement {@Element() 主机:HTMLDivElement;@State() 子项:Array= [];componentWillLoad() {let slotted = this.host.shadowRoot.querySelector('slot') as HTMLSlotElement;this.children = slotted.assignedNodes().filter((node) => { return node.nodeName !== '#text'; });}使成为() {返回 (<div><插槽/><ul>{this.children.map(child => { return <li innerHTML={child.outerHTML}></li>; })}

);}}

这不是最佳解决方案,它要求插槽的样式应将 display 设置为 none(因为您不想显示它).此外,它只适用于只需要渲染而不需要事件或其他任何东西的简单元素(因为它只将它们用作 html 字符串而不是用作对象).

I'm currently experimenting with StencilJS to create some web components.

Now I know that there is <slot /> and named slots and all that stuff. Coming from React, I guess slot is similar to children in React. You can do a lot of stuff using children in React. Things I often did:

  1. Check if any children are provided
  2. Iterate over children to do something to each child (e.g. wrap it in a div with a class etc.)

How would you do that using slot/web components/stencilJS?

I can get the Host Element of my web component in Stencil using

@Element() hostElement: HTMLElement;

I use my component like

<my-custom-component>
  <button>1</button>
  <button>2</button>
  <button>3</button>
</my-custom-component>

I want to render something like

render() {
  return slottedChildren ?
    <span>No Elements</span> :
    <ul class="my-custom-component">
      slottedChildren.map(child => <li class="my-custom-element>{child}</li>)
    </ul>;
}

Kind regards

解决方案

Using slots you don't need to put a condition in your render function. You can put the no children element (in your example the span) inside the slot element and if no children are provided to the slot it will fall back to it. For example:

render() {
    return (
        <div>
            <slot><span>no elements</span></slot>
        </div>
    );
}

Answering the comment you wrote - you can do such a thing but with some coding and not out of the box. Every slot element has an assignedNodes function. Using that knowledge and the understanding of Stencil component life cycle you can do something such as:

import {Component, Element, State} from '@stencil/core';

@Component({
    tag: 'slotted-element',
    styleUrl: 'slotted-element.css',
    shadow: true
})
export class SlottedElement {
    @Element() host: HTMLDivElement;
    @State() children: Array<any> = [];

    componentWillLoad() {
        let slotted = this.host.shadowRoot.querySelector('slot') as HTMLSlotElement;
        this.children = slotted.assignedNodes().filter((node) => { return node.nodeName !== '#text'; });
    }

    render() {
        return (
            <div>
                <slot />
                <ul>
                    {this.children.map(child => { return <li innerHTML={child.outerHTML}></li>; })}
                </ul>
            </div>
        );
    }
}

This is not an optimal solution and it will require that the style of the slot should have display set to none (cause you don't want to show it). Also, it will only work with simple elements that only need rendering and not requiring events or anything else (cause it only uses them as html string and not as objects).

这篇关于Web 组件:如何与孩子一起工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
其他开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆