跳至主要內容

$props

元件的輸入稱為 *props*,是 *properties* 的縮寫。您將 props 傳遞給元件,就像將屬性傳遞給元素一樣

App
<script>
	import MyComponent from './MyComponent.svelte';
</script>

<MyComponent adjective="cool" />

另一方面,在 MyComponent.svelte 內部,我們可以使用 $props 符文接收 props...

MyComponent
<script>
	let props = $props();
</script>

<p>this component is {props.adjective}</p>

...雖然更常見的做法是解構您的 props

MyComponent
<script>
	let { adjective } = $props();
</script>

<p>this component is {adjective}</p>

預設值

解構允許我們宣告預設值,如果父元件未設定給定的 prop,則會使用這些值

let { let adjective: anyadjective = '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();

https://svelte.dev.org.tw/docs/svelte/$props

$props
();

預設值不會轉換為反應式狀態代理(有關詳細資訊,請參閱更新 props

重新命名 props

我們也可以使用解構賦值來重新命名 props,如果它們是無效的識別符號,或是像 super 這樣的 JavaScript 關鍵字,則這是必要的

let { super: let trouper: anytrouper = '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();

https://svelte.dev.org.tw/docs/svelte/$props

$props
();

剩餘 props

最後,我們可以使用剩餘屬性來取得,嗯,其餘的 props

let { let a: anya, let b: anyb, let c: anyc, ...let others: anyothers } = function $props(): any

Declares the props that a component accepts. Example:

let { optionalProp = 42, requiredProp, bindableProp = $bindable() }: { optionalProp?: number; requiredProps: string; bindableProp: boolean } = $props();

https://svelte.dev.org.tw/docs/svelte/$props

$props
();

更新 props

當 prop 本身更新時,元件內部的 prop 參考也會更新 — 當 App.svelte 中的 count 變更時,它也會在 Child.svelte 內部變更。但是子元件能夠暫時覆寫 prop 值,這對於未儲存的臨時狀態非常有用 (範例)

App
<script>
	import Child from './Child.svelte';

	let count = $state(0);
</script>

<button onclick={() => (count += 1)}>
	clicks (parent): {count}
</button>

<Child {count} />
Child
<script>
	let { count } = $props();
</script>

<button onclick={() => (count += 1)}>
	clicks (child): {count}
</button>

雖然您可以暫時重新賦值 props,但不應變更 props,除非它們是可綁定的

如果 prop 是常規物件,則變更將不會產生任何效果 (範例)

App
<script>
	import Child from './Child.svelte';
</script>

<Child object={{ count: 0 }} />
Child
<script>
	let { object } = $props();
</script>

<button onclick={() => {
	// has no effect
	object.count += 1
}}>
	clicks: {object.count}
</button>

但是,如果 prop 是反應式狀態代理,則變更產生效果,但您會看到ownership_invalid_mutation警告,因為元件正在變更不「屬於」它的狀態 (範例)

App
<script>
	import Child from './Child.svelte';

	let object = $state({count: 0});
</script>

<Child {object} />
Child
<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 宣告的 prop 的預設值保持不變 — 它不會轉換為反應式狀態代理 — 這表示變更不會導致更新 (範例)

Child
<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>

總結:請勿變更 props。請使用回呼 props 來傳達變更,或者 — 如果父元件和子元件應共用同一個物件 — 請使用$bindable符文。

類型安全

您可以像對待任何其他變數宣告一樣,透過註解您的 props 來為您的元件新增類型安全。在 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>

建議新增類型,因為它可以確保使用您元件的人員可以輕鬆發現他們應該提供的 props。

在 GitHub 上編輯此頁面

上一頁 下一頁