简体   繁体   English

是否可以在 StencilJS 中延迟渲染组件?

[英]Is it possible to lazy render component in StencilJS?

As you want to build complex component, it would be great if you can wrap any DOM with component such as "lazy-load" component with condition (@Prop() condition: boolean) so to illustrate what I want:当您想要构建复杂的组件时,如果您可以使用组件包装任何 DOM,例如带有条件(@Prop() 条件:布尔值)的“延迟加载”组件,这样就可以说明我想要什么:

<lazy-load condition={some boolean condition, like certain link get clicked and section is now active}>
  <data-fetch>
  </data-fetch>
</lazy-load>

in this example, "data-fetch" will make a HTTP call to grab some large data , and I want to defer this component added to DOM until condition we specify in the lazy-load component to be true.在这个例子中, “data-fetch”将调用 HTTP 来获取一些大数据,我想推迟这个组件添加到 DOM,直到我们在延迟加载组件中指定的条件为真。

So I started to implement render() of lazy-load component as something along the line of所以我开始将延迟加载组件的 render() 实现为沿线的东西

@Prop() condition: boolean;

render() {
  if(!this.condition) {
    return null;
  }
  return (
    <slot/>
  );
}

and try to use it as并尝试将其用作

<lazy-load condition={false}>
  <data-fetch>
  </data-fetch>
</lazy-load>

but no matter what I tried, data-fetch component get added to DOM (and while we can set visibility to hide element, we would waste HTTP call) I understand I can put the same condition in the data-fetch itself and then not make a fetch call when condition is false, but if possible I want generic wrapper component to achieve this (if you are familiar with AngularJS or Angular, I want to find a way to do equivalent of ng-if and *ngIf off of generic wrapper component)但无论我尝试什么,数据获取组件都会添加到 DOM(虽然我们可以将可见性设置为隐藏元素,但我们会浪费 HTTP 调用)我知道我可以在数据获取本身中放置相同的条件,然后不做条件为 false 时的 fetch 调用,但如果可能的话,我希望通用包装器组件来实现这一点(如果您熟悉 AngularJS 或 Angular,我想找到一种方法来执行等效于通用包装器组件的 ng-if 和 *ngIf )

Maybe this is a limitation due to how "slot" tag supposed to work?也许这是由于“插槽”标签应该如何工作而造成的限制? (also, I'm using it with @Component({shadow: false}) so I know I'm not using standard shadowDOM from the web component spec so maybe what I'm trying to do is not feasible? (另外,我将它与 @Component({shadow: false}) 一起使用,所以我知道我没有使用 web 组件规范中的标准 shadowDOM,所以也许我想要做的事情不可行?

Thank you very much for your time in advance to even read this question and I appreciate any help I can get.非常感谢您提前抽出时间阅读这个问题,我很感激我能得到的任何帮助。 I feel if we can do this, we might be able to build component that can quickly differ loading until whenever we feel it should load/render.我觉得如果我们能做到这一点,我们可能能够构建可以快速加载不同的组件,直到我们认为它应该加载/渲染。

Yeah it's an issue with not using shadow: true , because in the polyfill the slotted content just becomes part of the light DOM (but gets placed where the slot element is).是的,不使用shadow: true是个问题,因为在 polyfill 中,开槽的内容只是成为 light DOM 的一部分(但被放置在 slot 元素所在的位置)。 Beware that even if you enable Shadow DOM, it'll still fallback to the polyfill if the browser doesn't support it.请注意,即使您启用了 Shadow DOM,如果浏览器不支持它,它仍然会回退到 polyfill。 You could raise an issue about this in Github but I'm not sure if/how it would be possible to solve this "dynamic slot" problem.您可以在 Github 中提出有关此问题的问题,但我不确定是否/如何解决此“动态插槽”问题。

But I think you can take a simpler approach:但我认为您可以采取更简单的方法:

{myCondition && <data-fetch />}

That way the data-fetch element will only be added once the condition becomes true.这样,只有在条件为真时才会添加data-fetch元素。

You could also refactor this into a functional component:您还可以将其重构为功能组件:

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>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM