props を使うと親コンポーネントと子コンポーネント間で値を割と利できることはわかっているが、孫コンポーネントまで値をやり取りする方法について考えた。
構成
以下のコンポーネント構成を考える。
1 2 3 4
| +- 親コンポーネント(App.svelte) +- 子コンポーネント(AppForm.svelte) +- 孫コンポーネント(AppInput.svelte) +- 孫コンポーネント(AppInput.svelte)
|
親コンポーネント( src/App.svelte )
1 2 3 4 5 6 7 8 9 10
| <script lang="ts"> let message: string = 'Hello, world' import AppForm from './AppForm.svelte'; import AppLabel from './AppLabel.svelte'; </script>
<h1>{message}</h1>
<AppLabel>Name</AppLabel> <AppForm bind:value={message}></AppForm>
|
1 2 3 4 5 6
| <script lang="ts"> import AppInput from './AppInput.svelte'; export let value: string = ''; </script>
<AppInput bind:value></AppInput>
|
孫コンポーネント( src/AppLabel.svelte )
1 2 3 4
| <script> </script>
<label><slot></slot></label>
|
1 2 3 4 5
| <script lang="ts"> export let value: string = ''; </script>
<input bind:value>
|
拡張バージョン
<input>
タグにフォームの内容を上位コンポーネントから伝えるように拡張してみる。
src/App.svelte
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| <script lang="ts"> let first_name: string = 'John' let last_name: string = 'Smith' import AppForm from './AppForm.svelte'; </script>
<h1>{first_name} {last_name}</h1>
<AppForm bind:value={first_name} name="first_name" type="text" title="First Name" /> <AppForm bind:value={last_name} name="last_name" type="test" title="Last Name" />
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| <script lang="ts"> import AppInput from './AppInput.svelte'; import AppLabel from './AppLabel.svelte'; export let name: string = ''; export let type: string = ''; export let value: string = ''; export let title: string = ''; </script>
<AppLabel name={name} title={title} /> <AppInput type={type} name={name} bind:value />
|
src/AppLabel.svelte
1 2 3 4 5 6
| <script lang="ts"> export let name:string = ''; export let title:string = ''; </script>
<label for={name}>{title}</label>
|
1 2 3 4 5 6 7 8 9 10 11
| <script lang="ts"> export let value: string = ''; export let type: string = ''; export let name: string; const props = { type, name, } </script>
<input {...props} bind:value/>
|