$props
コンポーネントへの入力は、プロパティの略であるpropsと呼ばれます。要素に属性を渡すのと同じように、コンポーネントにpropsを渡します。
<script>
import MyComponent from './MyComponent.svelte';
</script>
<MyComponent adjective="cool" />
一方、`MyComponent.svelte` の内部では、`$props` ルーンを使用してプロパティを受け取ることができます…
<script>
let props = $props();
</script>
<p>this component is {props.adjective}</p>
…しかし、より一般的には、プロパティをデストラクチャリングします。
<script>
let { adjective } = $props();
</script>
<p>this component is {adjective}</p>
フォールバック値
デストラクチャリングにより、親コンポーネントが特定のプロパティを設定していない場合に使用されるフォールバック値を宣言できます。
let { let adjective: any
adjective = 'happy' } = function $props(): any
Declares the props that a component accepts. Example:
let { optionalProp = 42, requiredProp, bindableProp = $bindable() }: { optionalProp?: number; requiredProps: string; bindableProp: boolean } = $props();
$props();
フォールバック値は、リアクティブな状態プロキシに変換されません(詳細についてはプロパティの更新を参照してください)。
プロパティ名の変更
デストラクチャリング代入を使用してプロパティの名前を変更することもできます。これは、無効な識別子である場合、または`super`などのJavaScriptキーワードである場合に必要です。
let { super: let trouper: any
trouper = 'lights are gonna find me' } = function $props(): any
Declares the props that a component accepts. Example:
let { optionalProp = 42, requiredProp, bindableProp = $bindable() }: { optionalProp?: number; requiredProps: string; bindableProp: boolean } = $props();
$props();
レストプロパティ
最後に、レストプロパティを使用して、残りのプロパティを取得できます。
let { let a: any
a, let b: any
b, let c: any
c, ...let others: any
others } = function $props(): any
Declares the props that a component accepts. Example:
let { optionalProp = 42, requiredProp, bindableProp = $bindable() }: { optionalProp?: number; requiredProps: string; bindableProp: boolean } = $props();
$props();
プロパティの更新
コンポーネント内のプロパティへの参照は、プロパティ自体が更新されると更新されます。`App.svelte` で `count` が変更されると、`Child.svelte` の内部でも変更されます。しかし、子コンポーネントはプロパティ値を一時的に上書きできます。これは、保存されていない一時的な状態に役立ちます(デモ)。
<script>
import Child from './Child.svelte';
let count = $state(0);
</script>
<button onclick={() => (count += 1)}>
clicks (parent): {count}
</button>
<Child {count} />
<script>
let { count } = $props();
</script>
<button onclick={() => (count += 1)}>
clicks (child): {count}
</button>
プロパティを一時的に再代入することはできますが、バインド可能でない限り、プロパティを変更しないでください。
プロパティが通常のオブジェクトの場合、変更は効果がありません(デモ)。
<script>
import Child from './Child.svelte';
</script>
<Child object={{ count: 0 }} />
<script>
let { object } = $props();
</script>
<button onclick={() => {
// has no effect
object.count += 1
}}>
clicks: {object.count}
</button>
しかし、プロパティがリアクティブな状態プロキシの場合、変更は影響しますが、コンポーネントはそれに「属さない」状態を変更しているため、`ownership_invalid_mutation`警告が表示されます(デモ)。
<script>
import Child from './Child.svelte';
let object = $state({count: 0});
</script>
<Child {object} />
<script>
let { object } = $props();
</script>
<button onclick={() => {
// will cause the count below to update,
// but with a warning. Don't mutate
// objects you don't own!
object.count += 1
}}>
clicks: {object.count}
</button>
`$bindable`で宣言されていないプロパティのフォールバック値はそのまま残され、リアクティブな状態プロキシに変換されないため、変更は更新を引き起こしません(デモ)。
<script>
let { object = { count: 0 } } = $props();
</script>
<button onclick={() => {
// has no effect if the fallback value is used
object.count += 1
}}>
clicks: {object.count}
</button>
要約すると、プロパティを変更しないでください。変更を伝えるにはコールバックプロパティを使用するか、親と子が同じオブジェクトを共有する場合は、`$bindable` ルーンを使用してください。
型安全性
他の変数宣言と同様に、プロパティにアノテーションを付けることで、コンポーネントに型安全性を追加できます。TypeScriptでは、次のようになります…
<script lang="ts">
let { adjective }: { adjective: string } = $props();
</script>
…JSDocでは、次のようにできます。
<script>
/** @type {{ adjective: string }} */
let { adjective } = $props();
</script>
もちろん、型宣言とアノテーションを分離することもできます。
<script lang="ts">
interface Props {
adjective: string;
}
let { adjective }: Props = $props();
</script>
コンポーネントを使用する人が簡単にどのプロパティを提供すべきかを見つけることができるため、型の追加をお勧めします。