是否可以在 StencilJS 中延迟渲染组件?
Is it possible to lazy render component in StencilJS?
因为你想构建复杂的组件,如果你能用组件包装任何 DOM 就好了,比如带条件的“延迟加载”组件 (@Prop() condition: boolean) 这样说明我想要什么:
<lazy-load condition={some boolean condition, like certain link get clicked and section is now active}>
<data-fetch>
</data-fetch>
</lazy-load>
在此示例中,“data-fetch”将进行 HTTP 调用以获取一些大数据,我想将此组件添加到 DOM 直到我们在延迟加载组件中指定的条件为真。
所以我开始将延迟加载组件的 render() 实现为
@Prop() condition: boolean;
render() {
if(!this.condition) {
return null;
}
return (
<slot/>
);
}
并尝试将其用作
<lazy-load condition={false}>
<data-fetch>
</data-fetch>
</lazy-load>
但无论我尝试什么,数据获取组件都会添加到 DOM(虽然我们可以将可见性设置为隐藏元素,但我们会浪费 HTTP 调用)我知道我可以将相同的条件放入数据获取本身,然后在条件为假时不进行获取调用,但如果可能的话,我希望通用包装器组件实现这一点(如果您熟悉 AngularJS 或 Angular,我想找到一种方法来完成通用包装器组件的 ng-if 和 *ngIf 的等效操作)
也许这是一个限制,因为“slot”标签应该如何工作?(另外,我将它与 @Component({shadow: false}) 一起使用,所以我知道我没有使用 Web 组件规范中的标准阴影 DOM 所以也许我正在尝试做的事情不可行?
非常感谢您提前抽出时间阅读这个问题,我很感激能得到的任何帮助。我觉得如果我们能做到这一点,我们也许能够构建可以快速改变负载的组件,直到我们认为应该 load/render.
是的,不使用 shadow: true
是个问题,因为在 polyfill 中,开槽内容只是成为光的一部分 DOM(但被放置在槽元素所在的位置)。请注意,即使您启用了 Shadow DOM,如果浏览器不支持它,它仍然会回退到 polyfill。您可以在 Github 中提出有关此问题的问题,但我不确定 if/how 是否有可能解决此“动态插槽”问题。
但我认为你可以采取更简单的方法:
{myCondition && <data-fetch />}
这样 data-fetch
元素只会在条件变为真时添加。
您也可以将其重构为功能组件:
import { FunctionalComponent } from '@stencil/core';
interface Props {
if: boolean;
}
export const LazyLoad: FunctionalComponent<Props> = ({ if }, children) =>
if && children;
import { LazyLoad } from './LazyLoad';
<LazyLoad if={condition}>
<data-fetch />
</LazyLoad>
因为你想构建复杂的组件,如果你能用组件包装任何 DOM 就好了,比如带条件的“延迟加载”组件 (@Prop() condition: boolean) 这样说明我想要什么:
<lazy-load condition={some boolean condition, like certain link get clicked and section is now active}>
<data-fetch>
</data-fetch>
</lazy-load>
在此示例中,“data-fetch”将进行 HTTP 调用以获取一些大数据,我想将此组件添加到 DOM 直到我们在延迟加载组件中指定的条件为真。
所以我开始将延迟加载组件的 render() 实现为
@Prop() condition: boolean;
render() {
if(!this.condition) {
return null;
}
return (
<slot/>
);
}
并尝试将其用作
<lazy-load condition={false}>
<data-fetch>
</data-fetch>
</lazy-load>
但无论我尝试什么,数据获取组件都会添加到 DOM(虽然我们可以将可见性设置为隐藏元素,但我们会浪费 HTTP 调用)我知道我可以将相同的条件放入数据获取本身,然后在条件为假时不进行获取调用,但如果可能的话,我希望通用包装器组件实现这一点(如果您熟悉 AngularJS 或 Angular,我想找到一种方法来完成通用包装器组件的 ng-if 和 *ngIf 的等效操作)
也许这是一个限制,因为“slot”标签应该如何工作?(另外,我将它与 @Component({shadow: false}) 一起使用,所以我知道我没有使用 Web 组件规范中的标准阴影 DOM 所以也许我正在尝试做的事情不可行?
非常感谢您提前抽出时间阅读这个问题,我很感激能得到的任何帮助。我觉得如果我们能做到这一点,我们也许能够构建可以快速改变负载的组件,直到我们认为应该 load/render.
是的,不使用 shadow: true
是个问题,因为在 polyfill 中,开槽内容只是成为光的一部分 DOM(但被放置在槽元素所在的位置)。请注意,即使您启用了 Shadow DOM,如果浏览器不支持它,它仍然会回退到 polyfill。您可以在 Github 中提出有关此问题的问题,但我不确定 if/how 是否有可能解决此“动态插槽”问题。
但我认为你可以采取更简单的方法:
{myCondition && <data-fetch />}
这样 data-fetch
元素只会在条件变为真时添加。
您也可以将其重构为功能组件:
import { FunctionalComponent } from '@stencil/core';
interface Props {
if: boolean;
}
export const LazyLoad: FunctionalComponent<Props> = ({ if }, children) =>
if && children;
import { LazyLoad } from './LazyLoad';
<LazyLoad if={condition}>
<data-fetch />
</LazyLoad>