【问题标题】:How can get custom tags inside web component如何在 Web 组件中获取自定义标签
【发布时间】:2021-01-08 22:00:39
【问题描述】:

我是 stenciljs 的 webcomponents 新手,我正在测试创建一个选择,这个代码的想法是创建和呈现选择:

<rhx-select label-text="A select web component">
      <rhx-select-item value="1" text="option 1"/>
      <rhx-select-item value="2" text="option 2"/>
</rhx-select>

我遇到的问题是如何获取 Web 组件中的标签?

这是我的代码:

import { Component, h, Prop, } from '@stencil/core';

@Component({
  tag: 'rhx-select',
  styleUrl: 'select.css',
  shadow: true,
})

export class RhxSelect {
    @Prop() labelText: string = 'select-rhx';

    @Prop() id: string;
    
    @Element() el: HTMLElement;

    renderOptions() {
        let data = Array.from(this.el.querySelectorAll('rhx-select-item'));
        return data.map((e) =>{
            <option value={e.attributes.getNamedItem('value').value}>{e.attributes.getNamedItem('text').value}</option>
        });
    }

    render(){
        return (
            <div>
                
                <label htmlFor={this.id}>
                    {this.labelText}
                </label>

                <select id={this.id} class="rhx-select">
                  {this.renderOptions()}
                </select>

            </div>
        )
    }   
}

感谢您的宝贵时间。

【问题讨论】:

  • &lt;script src="path/to/bundle.js" defer&gt;&lt;/script&gt; 一样简单地添加你的 webcomponents 包。这可以确保在组件初始化之前解析 DOM。
  • 这能回答你的问题吗? stackoverflow.com/questions/49786436/…

标签: web-component stenciljs


【解决方案1】:

如果你添加 @Element() 装饰器,你可以用 vanilla JS 解析孩子:

getItems() {
  return Array.from(this.el.querySelectorAll('rhx-select-item'));
}

然后,您可以随意使用这些元素及其属性/属性,例如生成&lt;option&gt; 元素的列表。

一个很好的例子是ion-select,它在childOpts() getter 函数中获取孩子。

要记住的几件事:

  1. 您可能希望隐藏带有display: none 的项目
  2. 如果选项在初始加载后可能会发生变化,您需要监听这些变化。 Ionic 使用watchForOptions function

【讨论】:

  • 嗨@Thomas,谢谢你的回答。我只是添加了呈现选项的功能,但没有发生任何事情。你可以看到下面的代码和html渲染链接:gistrender pic
  • 看起来项目是嵌套的。尝试非自闭标签 (&lt;/rhx-select-item&gt;)
【解决方案2】:

this.el.querySelectorAll 在组件渲染一次之前不会返回任何元素,以便它的子元素在 DOM 中可用。因此,您将不得不使用类似 componentDidLoad 的钩子:

export class RhxSelect {
  // ...

  @State()
  items: HTMLRhxSelectItemElement[] = [];

  componentDidLoad() {
    this.items = Array.from(this.el.querySelectorAll('rhx-select-item'));
  }

  render() {
    return (
      <div>
        <label htmlFor={this.id}>
            {this.labelText}
        </label>

        <select id={this.id} class="rhx-select">
          {this.items.map(item => (
            <option value={item.getAttribute('value')}>{item.getAttribute('text')}</option>
          ))}
        </select>
      </div>
    )
  }
}

但请注意,componentDidLoad 仅在组件加载后执行一次。如果您希望您的组件支持对选项的动态更改,那么您将不得不使用其他东西,例如componentDidRender,但您还必须确保您不会以无限渲染循环告终。通过组合不同的生命周期方法,还有几种方法可以解决这个问题。

有关所有可用生命周期方法的列表,请参阅 https://stenciljs.com/docs/component-lifecycle

【讨论】:

    猜你喜欢
    • 2018-02-23
    • 1970-01-01
    • 2021-03-13
    • 2014-09-03
    • 2018-04-21
    • 2014-11-16
    • 1970-01-01
    • 2013-05-28
    • 1970-01-01
    相关资源
    最近更新 更多