概要
Astroでsvelteファイルに簡単なカウンターボタンコンポーネントを実装した時に、
加算/減算ボタンを押下しても値がなぜか変化しない現象が発生しました。
下記が実装したコードになります。
index.astro
---
import Layout from '../layouts/Layout.astro';
import Counter from '../components/svelte/svelte/Counter.svelte'
---
<Layout>
<h1>Counter Sample</h1>
<Counter></Counter>
</Layout>
Counter.svelte
<script lang="ts">
let count = 0;
function add() {
count += 1;
}
function subtract() {
count -= 1;
}
</script>
<div class="counter">
<button on:click={subtract}>-</button>
<pre>{count}</pre>
<button on:click={add}>+</button>
</div>
<div class="message">
<slot />
</div>
<style>
.counter {
display: grid;
font-size: 2em;
grid-template-columns: repeat(3, minmax(0, 1fr));
margin-top: 2em;
place-items: center;
}
.message {
text-align: center;
}
</style>
原因
index.astroでクライアントディレクティブを指定していなかったこと。
- クライアントディレクティブとは?(公式doc参照)
クライアントディレクティブは、UIフレームワークコンポーネントがブラウザ上でどのように「動的に機能するか」を制御します。
特に指定がない限り、UIフレームワークコンポーネントはクライアントサイドでは静的なHTMLとして扱われます。client:*ディレクティブを使用しない場合、JavaScriptを含まない単なるHTMLとしてページに表示されます。
クライアントディレクティブを使えるのは、.astroファイルに直接インポートされたUIフレームワークコンポーネントに限ります。動的タグや、componentsプロップを通じて渡されるカスタムコンポーネント (EN)では、これらのディレクティブは使用できません。
修正後
UIフレームワークコンポーネントに対してクライアントディレクティブを指定しました。
client:loadを設定することで、ページの読み込みと同時に、コンポーネントのJavaScriptを読み込んで動的機能を有効化できるそうです。
index.astro
---
import Layout from '../layouts/Layout.astro';
import Counter from '../components/svelte/svelte/Counter.svelte'
---
<Layout>
<Counter client:load></Counter>
</Layout>
参考