Integraciones Framework UI
- No se puede importar componentes de Astro dentro de otros frameworks, aunque si se pueden pasar como
props. - Ejemplo con Svelte
Instalación
npx astro add svelte
bun astro add svelte
Componente
src\components\Counter.svelte
<script>
let count = $state(0);
console.log('Counter component loaded');
</script>
<h1>Counter</h1>
<h3>Value: {count}</h3>
<button onclick={() => count--}> -1 </button>
<button onclick={() => count++}> +1 </button>
Uso
---
import MainLayout from "src/layouts/MainLayout.astro";
import Counter from "@components/Counter.svelte";
---
<MainLayout title="Favoritos">
<div
style={{
height: "3000px",
backgroundColor: "blue",
opacity: 0.2,
}}
>
</div>
<Counter client:visible />
</MainLayout>
Props
Definir props
src\components\Counter.svelte
<script lang="ts">
interface Props {
initValue: number;
title: string;
}
let { initValue, title: description }: Props = $props();
let count = $state(initValue);
console.log("Counter component loaded");
</script>
<h1>{description}</h1>
<h3>Valor: {count}</h3>
<button onclick={() => count--}> -1 </button>
<button onclick={() => count++}> +1 </button>
// Otra forma de definir props
let {
initValue,
title
} : {
initValue: number;
title: string;
} = $props();
Enviar props
src\pages\favorites\index.astro
---
import Counter from "@components/Counter.svelte";
const initValue = 20;
---
<Counter
transition:persist="counter"
title="Svelte"
initValue={initValue}
client:load
/>
Preservar estado
- Para preservar el estado de un mismo componente en diferentes páginas
- Únicamente se agrega
transition:persist="algunnombre"en el componente repetido en las diferentes páginas transition:persist-propsno es necesario, se utilizaba ya que si dos componentes tienen diferentes valores en losprops, como elinitValuede un counter, entonces al hacercounter++no tomaba la referencia si ya se había cambiad en otro componente
Página 1
pagina1.astro
---
import Counter from "@components/Counter.svelte";
const initValue = 20;
---
<Counter
transition:persist="counter"
title="Svelte"
initValue={initValue}
client:visible
/>
Página 2
pagina2.astro
---
import Counter from "@components/Counter.svelte";
const initValue = 10;
---
<Counter
transition:persist="counter"
title="Svelte"
initValue={initValue}
client:visible
/>
Componentes de Astro como props
Svelte
src\components\Counter.svelte
<script lang="ts">
interface Props {
initValue: number;
children: any;
}
let { initValue, title: description, children }: Props = $props();
let count = $state(initValue);
</script>
{@render children?.()}
<p>Ejemplo con Svelte</p>
<h3>Valor: {count}</h3>
Pasando el componente Astro
src\pages\islands\index.astro
---
import Title from "@components/shared/Title.astro";
import Counter from "@components/Counter.svelte";
const initValue = 10;
---
<Counter
transition:persist="counter"
title="Svelte"
initValue={initValue}
client:visible
>
<Title>Titulo con Astro</Title>
</Counter>
View Transitions
- Ya que no es un componente de Astro, entonces se debe escribir manualmente
- Deben tener el mismo nombre, tanto en el componente de la integración, como Svelte, y en el componente de Astro.
Card.svelte
<img
src={imageSrc}
alt={pokemon.name}
width="96"
height="96"
style={`view-transition-name: ${pokemon.name}-image`}
/>
index.astro
<img
transition:name={`${name}-image`}
src={imageUrl}
alt={name}
/>