Skip to main content

bind:

数据通常是从父级流向子级。bind: 指令允许数据反向流动,从子级流向父级。

一般语法是 bind:property={expression},其中 expression 是一个 lvalue(即一个变量或一个对象属性)。当表达式的标识符与属性同名时,我们可以省略表达式——换句话说,这两者是等价的:

<input bind:value={value} />
<input bind:value />

Svelte 创建了一个事件监听器来更新绑定值。如果元素已经有一个相同事件的监听器,那个监听器会在绑定值更新之前触发。

大多数绑定是 双向的,这意味着对值的更改会影响元素,反之亦然。有一些绑定是 只读的,这意味着更改它们的值不会对元素产生影响。

函数绑定

您还可以使用 bind:property={get, set},其中 getset 是函数,允许您进行验证和转换:

<input bind:value={
	() => value,
	(v) => value = v.toLowerCase()}
/>

对于只读绑定如尺寸绑定get 值应为 null

<div
	bind:clientWidth={null, redraw}
	bind:clientHeight={null, redraw}
>...</div>

函数绑定在 Svelte 5.9.0 及更新版本中可用。

<input bind:value>

<input> 元素上使用 bind:value 指令绑定输入的 value 属性:

<script>
	let message = $state('hello');
</script>

<input bind:value={message} />
<p>{message}</p>

对于数字输入(type="number"type="range"),该值将被强制转换为数字(demo):

<script>
	let a = $state(1);
	let b = $state(2);
</script>

<label>
	<input type="number" bind:value={a} min="0" max="10" />
	<input type="range" bind:value={a} min="0" max="10" />
</label>

<label>
	<input type="number" bind:value={b} min="0" max="10" />
	<input type="range" bind:value={b} min="0" max="10" />
</label>

<p>{a} + {b} = {a + b}</p>

如果输入为空或无效(在 type="number" 的情况下),值为 undefined

自 5.6.0 版本开始,如果 <input>defaultValue 并且是表单的一部分,当表单被重置时,它将恢复为该值,而不是空字符串。请注意,对于初始渲染,除非绑定值为 nullundefined,否则绑定值优先。

<script>
	let value = $state('');
</script>

<form>
	<input bind:value defaultValue="not the empty string">
	<input type="reset" value="Reset">
</form>

请谨慎使用重置按钮,并确保用户在提交表单时不会意外点击它们。

<input bind:checked>

复选框和单选输入可以绑定 bind:checked

<label>
	<input type="checkbox" bind:checked={accepted} />
	接受条款和条件
</label>

自 5.6.0 版本开始,如果 <input>defaultChecked 属性并且是表单的一部分,当表单被重置时,它将恢复为该值,而不是 false。请注意,对于初始渲染,除非绑定值为 nullundefined,否则绑定值优先。

<script>
	let checked = $state(true);
</script>

<form>
	<input type="checkbox" bind:checked defaultChecked={true}>
	<input type="reset" value="Reset">
</form>

<input bind:group>

一起工作的 input 元素,比如单选框、复选框,可以使用 bind:group

<script>
	let tortilla = $state('Plain');

	/** @type {Array<string>} */
	let fillings = $state([]);
</script>

<!-- 分组的单选输入是互斥的 -->
<input type="radio" bind:group={tortilla} value="Plain" />
<input type="radio" bind:group={tortilla} value="Whole wheat" />
<input type="radio" bind:group={tortilla} value="Spinach" />

<!-- 分组的复选框输入填充一个数组 -->
<input type="checkbox" bind:group={fillings} value="Rice" />
<input type="checkbox" bind:group={fillings} value="Beans" />
<input type="checkbox" bind:group={fillings} value="Cheese" />
<input type="checkbox" bind:group={fillings} value="Guac (extra)" />

bind:group 仅在 input 位于同一 Svelte 组件中时才有效。

<input bind:files>

<input> 元素上使用 type="file" 时,您可以使用 bind:files 获取所选文件的 FileList。当您想以编程方式更新文件时,您始终需要使用 FileList 对象。目前无法直接构造 FileList 对象,因此您需要创建一个新的 DataTransfer 对象,并从中获取 files

<script>
	let files = $state();

	function clear() {
		files = new DataTransfer().files; // null 或 undefined 无效
	}
</script>

<label for="avatar">上传图片:</label>
<input accept="image/png, image/jpeg" bind:files id="avatar" name="avatar" type="file" />
<button onclick={clear}>清空</button>

FileList 对象也不能被修改,因此如果您想从列表中删除单个文件,则需要创建一个新的 DataTransfer 对象,并添加您想保留的文件。

DataTransfer 在服务器端 JavaScript 运行时可能不可用。将绑定到 files 的状态保持未初始化可以防止组件在服务端渲染时出现潜在错误。

<select bind:value>

<select> 值绑定对应于所选 <option>value 属性,可以是任何值(不仅仅是 DOM 中通常使用的字符串)。

<select bind:value={selected}>
	<option value={a}>a</option>
	<option value={b}>b</option>
	<option value={c}>c</option>
</select>

<select multiple> 元素的行为类似于复选框组。绑定的变量是一个数组,其中包含与每个选定的 <option>value 属性对应的条目。

<select multiple bind:value={fillings}>
	<option value="Rice">米饭</option>
	<option value="Beans">豆子</option>
	<option value="Cheese">奶酪</option>
	<option value="Guac (extra)">鳄梨(额外)</option>
</select>

<option> 的值与其文本内容匹配时,可以省略该属性。

<select multiple bind:value={fillings}>
	<option>米饭</option>
	<option>豆子</option>
	<option>奶酪</option>
	<option>鳄梨(额外)</option>
</select>

您可以通过给 <option> 添加一个 selected 属性(如果是 <select multiple>,那可以设置多个 selected 属性),为 <select> 设置默认值。

如果 <select> 是表单的一部分,在表单重置时将恢复到该选择。请注意,对于初始渲染,如果绑定的值不是 undefined,则绑定的值优先。

<select bind:value={selected}>
	<option value={a}>a</option>
	<option value={b} selected>b</option>
	<option value={c}>c</option>
</select>

<audio>

<audio> 元素有自己的一组绑定——五个双向绑定...

...以及七个只读绑定:

<audio src={clip} bind:duration bind:currentTime bind:paused></audio>

<video>

<video> 元素具有与 (audio)[#audio] 元素相同的所有绑定,外加只读的 videoWidthvideoHeight 绑定。

<img>

<img> 元素有两个只读绑定:

<details bind:open>

<details> 元素绑定到 open 属性。

<details bind:open={isOpen}>
	<summary>How do you comfort a JavaScript bug?</summary>
	<p>You console it.</p>
</details>

可编辑内容绑定

具有 contenteditable 属性的元素支持以下绑定:

innerTexttextContent 之间有微妙的差异

<div contenteditable="true" bind:innerHTML={html} />

尺寸

所有可见元素都有以下只读绑定,通过 ResizeObserver 测量:

<div bind:offsetWidth={width} bind:offsetHeight={height}>
	<Chart {width} {height} />
</div>

display: inline 元素没有宽度或高度(除了具有“固有”尺寸的元素,如 <img><canvas>),并且无法通过 ResizeObserver 进行观察。您需要将这些元素的 display 样式更改为其他值,例如 inline-block

bind:this

bind:this={dom_node}

要获取对 DOM 节点的引用,请使用 bind:this。该值在组件挂载之前是 undefined —— 换句话说,您应该在 effect 或事件处理程序内部读取它,而不是在组件初始化期间读取:

<script>
	/** @type {HTMLCanvasElement} */
	let canvas;

	$effect(() => {
		const ctx = canvas.getContext('2d');
		drawStuff(ctx);
	});
</script>

<canvas bind:this={canvas} />

组件也支持 bind:this,允许您以编程方式与组件实例进行交互。

App
<ShoppingCart bind:this={cart} />

<button onclick={() => cart.empty()}> 清空购物车 </button>
ShoppingCart
<script>
	// 所有实例导出都可在实例对象上使用
	export function empty() {
		// ...
	}
</script>
<script lang="ts">
	// 所有实例导出都可在实例对象上使用
	export function empty() {
		// ...
	}
</script>

bind:property for components

bind:property={variable}

您可以使用与元素相同的语法绑定组件属性。

<Keypad bind:value={pin} />

虽然 Svelte 的 props 在不绑定的情况下是响应式的,但默认情况下这种响应性只能向下流入组件。使用 bind:property 可以让组件内部对属性的更改向上传递出组件。

要将属性标记为可绑定的,请使用 $bindable 符文:

<script>
	let { readonlyProperty, bindableProperty = $bindable() } = $props();
</script>

将属性声明为可绑定意味着它 可以 使用 bind:,但不是说它 必须 使用 bind:

可绑定属性可以有一个后备值:

<script>
	let { bindableProperty = $bindable('fallback value') } = $props();
</script>

此后备值 在属性 被绑定时适用。当属性被绑定并且存在后备值时,父级必须提供一个不同于 undefined 的值,否则会抛出运行时错误。这可以防止出现难以推理的情况,即不清楚应该应用哪个值。

在 GitHub 编辑此页面

上一页 下一页