跳至主要内容

$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.js.cn/docs/svelte/$props

$props
();

回退值不会转换为反应式状态代理(有关详细信息,请参阅 更新 props

重命名 props

我们还可以使用解构赋值来重命名 props,如果它们是无效的标识符或 JavaScript 关键字(如 super),则需要这样做

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.js.cn/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.js.cn/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 是 可绑定的,否则您不应修改 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 上编辑此页面

上一页 下一页