Stenciljs:前置/附加插槽元素的正确方法是什么?
我在使用 Web 组件中的生命周期方法时遇到一些问题。
我们想要动态地排序作为槽传入的子元素。
为了说明这一点,此 Web 组件采用一个 prop,iconPos
,并将确定图标是否放置在插槽的开头或结尾。
<my-component iconPos="start">
<img src="/path/icon.svg" />
<div>{this.list}</div>
</my-component>
我没有任何运气让它与 ref
一起工作:
dc6b89e7.js:2926 TypeError: Cannot read properties of undefined (reading 'prepend')
这就是我所拥有的far:
@State() slotElement!: HTMLDivElement;
@Prop() iconPos: 'start' | 'end';
...
private createSlots() {
switch (this.iconPos) {
case 'start':
this.slotElement.prepend(<img />);
break;
case 'end':
this.slotElement.append(<img />);
break;
default:
throw new Error(
`Invalid value \`${this.iconPos}\`, passed into \`iconPos\`. Expected valid values are \`start\`, \`end\``.
);
}
}
render() {
return (
// iconPos="start"
<parent-component>
<div ref={(el) => (this.slotElement= el as HTMLDivElement)}>
<slot></slot>
</div>
</parent-component>
)
}
如果可能的话,我宁愿不使用 CSS 解决方案。任何帮助将不胜感激!
I am having some trouble with the lifecycle methods in web components.
We want to dynamically order child elements being passed in as slots.
To illustrate, this web component takes a prop, iconPos
, and will determine whether the icon will be placed at the start or end of the slot.
<my-component iconPos="start">
<img src="/path/icon.svg" />
<div>{this.list}</div>
</my-component>
I haven't had any luck getting it working with ref
:
dc6b89e7.js:2926 TypeError: Cannot read properties of undefined (reading 'prepend')
Here's what I have so far:
@State() slotElement!: HTMLDivElement;
@Prop() iconPos: 'start' | 'end';
...
private createSlots() {
switch (this.iconPos) {
case 'start':
this.slotElement.prepend(<img />);
break;
case 'end':
this.slotElement.append(<img />);
break;
default:
throw new Error(
`Invalid value \`${this.iconPos}\`, passed into \`iconPos\`. Expected valid values are \`start\`, \`end\``.
);
}
}
render() {
return (
// iconPos="start"
<parent-component>
<div ref={(el) => (this.slotElement= el as HTMLDivElement)}>
<slot></slot>
</div>
</parent-component>
)
}
I would prefer to not use a CSS solution if possible. Any help would be much appreciated!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
开槽内容未移动到
元素;它反映了!!因此,所有样式和元素操作都必须在“lightDOM”中完成
对于(非常)长的阅读,请参阅:
::用于shadowDOM中嵌套子项的slotted CSS选择器slot
这意味着你必须在ligtDOM中
附加
你的元素:this.append(this.firstElementChild)
您无法在解析
innerHTML之前读取它;所以你需要等待innerHTML 元素被创建。这样你就会看到 DOM 的变化。更好的方法可能是不使用
并将图标和内容声明为属性,并让 Web 组件创建 HTML 。Slotted content is NOT MOVED to
<slot>
elements; it is reflected!!So all styling and element operations must be done in "lightDOM"
For (very) long read see:
::slotted CSS selector for nested children in shadowDOM slot
That means you have to
append
your elements in ligtDOM with:this.append(this.firstElementChild)
You can't read the
<my-component>
innerHTML before it is parsed; so you need to wait till the innerHTML elements are created. Thus you will see the DOM change.A better method might be to not use
<slot>
and declare your icon and content as attributes, and have the Web Component create the HTML.