Lui laai modules in Svelte

Hoe om jou komponent op aanvraag in te voer

Dinamiese invoer in Svelte

Wanneer jy in Svelte kodeer, kan jy die vereiste hê om slegs komponente op aanvraag te laai, wanneer dit werklik nodig is. React het hierdie probleem redelik meesterlik opgelos met sy "Suspense"-komponent. As jy iets soortgelyks in Svelte wil bereik, het ek goeie nuus vir jou.

Svelte "Suspense" sonder spanning

Basies wat nodig is, is om Svelte se ingeboude meganisme te gebruik om asynchrone funksie-oproepe in die komponent self te wag. Die volgende eenvoudige voorbeeld wys wat ek daarmee bedoel.

<script>
  // Dummy function, just so that we
  // have some async stuff.
	async function getData() {
		await new Promise(res => setTimeout(res, 1000));
		return { key: "value" };
	}
</script>

{#await getData()}
	<p>Fetching data...</p>
{:then res}
	<p>Accessing data: "key": "{res.key}"</p>
{:catch error}
	<p style="color: red">{error.message}</p>
{/await}

Soos u kan sien, wag ons eenvoudig op die funksie se terugkeerwaarde en gebruik dit dan in ons UI. Dieselfde tegniek kan gebruik word vir die invoer van hele modules.

Dinamiese invoer met Svelte

Met behulp van die dinamiese "invoer", beskikbaar in ES6, kan ons 'n eenvoudige lui komponent invoer skryf.

//
// Live demo:
// https://svelte.dev/repl/b7551180977d4e738b07d428f3172d5e?version=3.46.4
//

//
// App.svelte
// 

<h1>App title</h1>

{#await import("./Content.svelte") then Module}
	<Module.default subtitle="Subtilte as prop" />
{/await}
//
// Content.svelte
//

<script>
	export let subtitle;
</script>

<article>
  <h2>
		Content title
	</h2>
	<h3>
		{subtitle}
	</h3>
	<p>
		Content body.
	</p>
</article>

Deur op hierdie kennis te bou, is ons nou in staat om enige komponent lui te laai. 'n Praktiese voorbeeld wat ek eintlik vir spikze.club gebruik, is implementering van 'n enkele "Icon"-komponent wat die spesifieke ikoon op aanvraag laai.

<!--
  Source: https://carbon-icons-svelte.onrender.com/
-->
<script lang="ts">
  // Using a link so that 'clsx' can eliminate
  // all other variant compared to an enum, which
  // should lead to a smaller size at runtime.
  export let variant: "internal-link" | "external-link" | "section-link" | "close" | "add-circle";
  let cn: string = undefined;
  export { cn as class };
</script>

{#if variant === "external-link"}
  {#await import("carbon-icons-svelte/lib/ArrowUpRight20") then Icon}
    <Icon.default class={cn} />
  {/await}
{/if}

{#if variant === "internal-link"}
  {#await import("carbon-icons-svelte/lib/ArrowRight20") then Icon}
    <Icon.default class={cn} />
  {/await}
{/if}

{#if variant === "section-link"}
  {#await import("carbon-icons-svelte/lib/ArrowDown20") then Icon}
    <Icon.default class={cn} />
  {/await}
{/if}

{#if variant === "close"}
  {#await import("carbon-icons-svelte/lib/Close20") then Icon}
    <Icon.default class={cn} />
  {/await}
{/if}

{#if variant === "add-circle"}
  {#await import("carbon-icons-svelte/lib/AddAlt20") then Icon}
    <Icon.default class={cn} />
  {/await}
{/if}

Afsluit

Jy het gesien hoe om die dinamiese invoer vanaf ES6 te gebruik om bloot enige data op aanvraag in te voer. Aangesien dit van toepassing is op beide jou komponente sowel as derdeparty-biblioteke, is daar niks wat jou terughou om jou volgende Svelte-toepassing te skaal nie.