$bindable
通常情况下,props 是单向的,从父组件流向子组件。这使得理解应用中的数据流向变得容易。
在 Svelte 中,组件的 props 可以被绑定,这意味着数据也可以从子组件流向父组件。这不是你应该经常做的事情,但如果谨慎且适度地使用,可以简化你的代码。
这也意味着状态代理可以在子组件中被修改。
普通的 props 也可以被修改,但强烈不建议这样做 — 如果 Svelte 检测到一个组件正在修改它不”拥有”的状态,会发出警告。
要将一个 prop 标记为可绑定的,我们使用 $bindable 符文:
FancyInput
<script>
	let { value = $bindable(), ...props } = $props();
</script>
<input bind:value={value} {...props} />
<style>
	input {
		font-family: 'Comic Sans MS';
		color: deeppink;
	}
</style><script lang="ts">
	let { value = $bindable(), ...props } = $props();
</script>
<input bind:value={value} {...props} />
<style>
	input {
		font-family: 'Comic Sans MS';
		color: deeppink;
	}
</style>现在,使用 <FancyInput> 的组件可以添加 bind: 指令(demo):
/// App.svelte
<script>
	import FancyInput from './FancyInput.svelte';
	let message = $state('hello');
</script>
<FancyInput bind:value={message} />
<p>{message}</p>父组件不一定非要使用 bind: — 它可以只传递一个普通的 prop。有些父组件不想听取子组件要说的话。
在这种情况下,你可以为没有传递 prop 时指定一个后备值:
FancyInput
let { let value: anyvalue = function $bindable<"fallback">(fallback?: "fallback" | undefined): "fallback"Declares a prop as bindable, meaning the parent component can use bind:propName={value} to bind to it.
let { propName = $bindable() }: { propName: boolean } = $props();
$bindable('fallback'), ...let props: anyprops } = function $props(): anyDeclares the props that a component accepts. Example:
let { optionalProp = 42, requiredProp, bindableProp = $bindable() }: { optionalProp?: number; requiredProps: string; bindableProp: boolean } = $props();
$props();