虽然我知道这可能是一个糟糕的做法,但我需要构建StencilJS组件,以便在render()内,由于已经存在样式指南,我不想呈现组件标签本身,并且它希望在其中构建DOM。某种方式。这是我想要实现的-组件代码(从HTML或在另一个组件内):
<tab-header-list>
<tab-header label="tab 1"></tab-header>
<tab-header label="tab 2"></tab-header>
</tab-header-list>
渲染时,我希望生成的DOM类似于:
<tab-header-list>
<ul>
<li>tab 1</li>
<li>tab 2</li>
</ul>
</tab-header-list>
所以在tab-header-list render()函数中,我正在做
return (
<ul>
<slot/>
</ul>
);
我可以在tab-header render()函数中完成此操作
@Element() el: HTMLElement;
@Prop() label: string;
render() {
this.el.outerHTML = `<li>${this.label}</li>`;
}
得到我想要的东西,但是如何使用 TSX 做到这一点? (为简单起见,以上代码确实很简单,但是我真正需要构建的是带有事件等的更复杂的li标签,因此我想使用TSX)
试图将DOM存储到变量中,但是我不确定如何将其分配为this.el(outerHTML似乎是我可以提出的唯一方法,但是我觉得必须有更好的方法)
@Element() el: HTMLElement;
@Prop() label: string;
render() {
var tabheaderDOM = (<li>{this.label}</li>);
// how can I assign above DOM to this.el somehow?
//this.el.outerHTML = ?
}
感谢您能提供的任何帮助-在此先感谢您的宝贵时间!
答案 0 :(得分:1)
不幸的是,您不能使用没有标签的自定义元素,但是有一种解决方法:
您可以使用Host
元素作为结果标签的引用。
render () {
return (
<Host>....</Host>
)
}
然后,您可以在样式表中为其设置display
属性:
:host {
display: contents;
}
显示:内容使元素的子代看起来像是元素父代的直接子代,而忽略了元素本身
当心:它不适用于IE,Opera mini ... https://caniuse.com/#feat=css-display-contents
UPD:
如果您不使用shadowDOM
,则需要用以下标记名替换:host
:
tab-header {
display: contents;
}
答案 1 :(得分:0)
功能组件可能可以帮助您实现这一目标。它们只是返回TSX元素的函数的语法糖,因此它们与常规Stencil组件完全不同。主要区别在于它们不编译为Web组件,因此仅在TSX内工作。但是它们也不会导致多余的DOM节点,因为它们只是返回函数返回的模板。
让我们举个例子:
@Element() el: HTMLElement;
@Prop() label: string;
render() {
this.el.outerHTML = `<li>${this.label}</li>`;
}
您可以将其编写为功能组件:
import { FunctionalComponent } from '@stencil/core';
interface ListItemProps {
label: string;
}
export const ListItem: FunctionalComponent<ListItemProps> = ({ label }) => (
<li>{label}</li>
);
然后您可以像使用它
import { ListItem } from './ListItem';
@Component({ tag: 'my-comp' })
export class MyComp {
render() {
return (
<ul>
<ListItem label="tab 1" />
<ListItem label="tab 2" />
</ul>
);
}
}
将呈现为
<ul>
<li>tab 1</li>
<li>tab 2</li>
</ul>
除了标签属性,您还可以编写功能组件以将标签作为子代接受:
export const ListItem: FunctionalComponent = (_, children) => (
<li>{children}</li>
);
并像使用它
<ListItem>tab 1</ListItem>
BTW Host
实际上是一个功能组件。要了解有关功能组件(及其局限性)的更多信息,请参见https://stenciljs.com/docs/functional-components。