bind:
数据通常从父级向下流动到子级。bind:
指令允许数据以另一种方式流动,从子级流向父级。
¥Data ordinarily flows down, from parent to child. The bind:
directive allows data to flow the other way, from child to parent.
一般语法是 bind:property={expression}
,其中 expression
是左值(即变量或对象属性)。当表达式是与属性同名的标识符时,我们可以省略表达式 - 换句话说,它们是等效的:
¥The general syntax is bind:property={expression}
, where expression
is an lvalue (i.e. a variable or an object property). When the expression is an identifier with the same name as the property, we can omit the expression — in other words these are equivalent:
<input bind:value={value} />
<input bind:value />
Svelte 创建一个更新绑定值的事件监听器。如果元素已经具有同一事件的监听器,则将在更新绑定值之前触发该监听器。
¥Svelte creates an event listener that updates the bound value. If an element already has a listener for the same event, that listener will be fired before the bound value is updated.
大多数绑定都是双向的,这意味着对值的更改将影响元素,反之亦然。一些绑定是只读的,这意味着更改它们的值不会对元素产生影响。
¥Most bindings are two-way, meaning that changes to the value will affect the element and vice versa. A few bindings are readonly, meaning that changing their value will have no effect on the element.
函数绑定(Function bindings)
¥Function bindings
你还可以使用 bind:property={get, set}
,其中 get
和 set
是函数,允许你执行验证和转换:
¥You can also use bind:property={get, set}
, where get
and set
are functions, allowing you to perform validation and transformation:
<input bind:value={
() => value,
(v) => value = v.toLowerCase()}
/>
在像 尺寸绑定 这样的只读绑定的情况下,get
值应该是 null
:
¥In the case of readonly bindings like dimension bindings, the get
value should be null
:
<div
bind:clientWidth={null, redraw}
bind:clientHeight={null, redraw}
>...</div>
函数绑定在 Svelte 5.9.0 及更新版本中可用。
¥[!NOTE] Function bindings are available in Svelte 5.9.0 and newer.
<input bind:value>
<input>
元素上的 bind:value
指令绑定输入的 value
属性:
¥A bind:value
directive on an <input>
element binds the input’s value
property:
<script>
let message = $state('hello');
</script>
<input bind:value={message} />
<p>{message}</p>
在数字输入(type="number"
或 type="range"
)的情况下,该值将被强制转换为数字(demo):
¥In the case of a numeric input (type="number"
or type="range"
), the value will be coerced to a number (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
。
¥If the input is empty or invalid (in the case of type="number"
), the value is undefined
.
自 5.6.0 起,如果 <input>
具有 defaultValue
并且是表单的一部分,则在重置表单时它将恢复为该值而不是空字符串。请注意,对于初始渲染,除非绑定的值是 null
或 undefined
,否则绑定的值优先。
¥Since 5.6.0, if an <input>
has a defaultValue
and is part of a form, it will revert to that value instead of the empty string when the form is reset. Note that for the initial render the value of the binding takes precedence unless it is null
or undefined
.
<script>
let value = $state('');
</script>
<form>
<input bind:value defaultValue="not the empty string">
<input type="reset" value="Reset">
</form>
谨慎使用重置按钮,并确保用户在尝试提交表单时不会意外点击它们。
¥[!NOTE] Use reset buttons sparingly, and ensure that users won’t accidentally click them while trying to submit the form.
<input bind:checked>
复选框和单选输入可以与 bind:checked
绑定:
¥Checkbox and radio inputs can be bound with bind:checked
:
<label>
<input type="checkbox" bind:checked={accepted} />
Accept terms and conditions
</label>
自 5.6.0 起,如果 <input>
具有 defaultChecked
属性并且是表单的一部分,则在重置表单时它将恢复为该值而不是 false
。请注意,对于初始渲染,除非绑定的值是 null
或 undefined
,否则绑定的值优先。
¥Since 5.6.0, if an <input>
has a defaultChecked
attribute and is part of a form, it will revert to that value instead of false
when the form is reset. Note that for the initial render the value of the binding takes precedence unless it is null
or undefined
.
<script>
let checked = $state(true);
</script>
<form>
<input type="checkbox" bind:checked defaultChecked={true}>
<input type="reset" value="Reset">
</form>
<input bind:group>
一起工作的输入可以使用 bind:group
。
¥Inputs that work together can use bind:group
.
<script>
let tortilla = $state('Plain');
/** @type {Array<string>} */
let fillings = $state([]);
</script>
<!-- grouped radio inputs are mutually exclusive -->
<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" />
<!-- grouped checkbox inputs populate an array -->
<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)" />
仅当输入位于同一个 Svelte 组件中时,
bind:group
才有效。¥[!NOTE]
bind:group
only works if the inputs are in the same Svelte component.
<input bind:files>
在具有 type="file"
的 <input>
元素上,你可以使用 bind:files
来获取 所选文件的 FileList
个。当你想要以编程方式更新文件时,你始终需要使用 FileList
对象。目前无法直接构造 FileList
对象,因此你需要创建一个新的 DataTransfer
对象并从那里获取 files
。
¥On <input>
elements with type="file"
, you can use bind:files
to get the FileList
of selected files. When you want to update the files programmatically, you always need to use a FileList
object. Currently FileList
objects cannot be constructed directly, so you need to create a new DataTransfer
object and get files
from there.
<script>
let files = $state();
function clear() {
files = new DataTransfer().files; // null or undefined does not work
}
</script>
<label for="avatar">Upload a picture:</label>
<input accept="image/png, image/jpeg" bind:files id="avatar" name="avatar" type="file" />
<button onclick={clear}>clear</button>
FileList
对象也无法修改,因此如果你想从列表中删除单个文件,则需要创建一个新的 DataTransfer
对象并添加要保留的文件。
¥FileList
objects also cannot be modified, so if you want to e.g. delete a single file from the list, you need to create a new DataTransfer
object and add the files you want to keep.
DataTransfer
可能在服务器端 JS 运行时不可用。如果组件是服务器端渲染的,则将绑定到files
的状态保持未初始化状态可防止潜在的错误。¥[!NOTE]
DataTransfer
may not be available in server-side JS runtimes. Leaving the state that is bound tofiles
uninitialized prevents potential errors if components are server-side rendered.
<select bind:value>
<select>
值绑定对应于所选 <option>
上的 value
属性,可以是任何值(不仅仅是字符串,DOM 中通常如此)。
¥A <select>
value binding corresponds to the value
property on the selected <option>
, which can be any value (not just strings, as is normally the case in the 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
属性。
¥A <select multiple>
element behaves similarly to a checkbox group. The bound variable is an array with an entry corresponding to the value
property of each selected <option>
.
<select multiple bind:value={fillings}>
<option value="Rice">Rice</option>
<option value="Beans">Beans</option>
<option value="Cheese">Cheese</option>
<option value="Guac (extra)">Guac (extra)</option>
</select>
当 <option>
的值与其文本内容匹配时,可以省略该属性。
¥When the value of an <option>
matches its text content, the attribute can be omitted.
<select multiple bind:value={fillings}>
<option>Rice</option>
<option>Beans</option>
<option>Cheese</option>
<option>Guac (extra)</option>
</select>
你可以通过将 selected
属性添加到最初应选择的 <option>
(或选项,对于 <select multiple>
)来为 <select>
提供默认值。如果 <select>
是表单的一部分,则在重置表单时它将恢复为该选择。请注意,对于初始渲染,如果不是 undefined
,则绑定的值优先。
¥You can give the <select>
a default value by adding a selected
attribute to the<option>
(or options, in the case of <select multiple>
) that should be initially selected. If the <select>
is part of a form, it will revert to that selection when the form is reset. Note that for the initial render the value of the binding takes precedence if it’s not 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>
elements have their own set of bindings — five two-way ones...
...和七个只读绑定:
¥...and seven readonly ones:
<audio src={clip} bind:duration bind:currentTime bind:paused></audio>
<video>
<video>
元素具有与 [#audio] 元素相同的所有绑定,以及只读 videoWidth
和 videoHeight
绑定。
¥<video>
elements have all the same bindings as [#audio] elements, plus readonly videoWidth
and videoHeight
bindings.
<img>
<img>
元素有两个只读绑定:
¥<img>
elements have two readonly bindings:
<details bind:open>
<details>
元素支持绑定到 open
属性。
¥<details>
elements support binding to the open
property.
<details bind:open={isOpen}>
<summary>How do you comfort a JavaScript bug?</summary>
<p>You console it.</p>
</details>
内容可编辑绑定(Contenteditable bindings)
¥Contenteditable bindings
具有 contenteditable
属性的元素支持以下绑定:
¥Elements with the contenteditable
attribute support the following bindings:
有
innerText
和textContent
之间的细微差别。¥[!NOTE] There are subtle differences between
innerText
andtextContent
.
<div contenteditable="true" bind:innerHTML={html} />
尺寸(Dimensions)
¥Dimensions
所有可见元素都具有以下只读绑定,使用 ResizeObserver
进行测量:
¥All visible elements have the following readonly bindings, measured with a ResizeObserver
:
<div bind:offsetWidth={width} bind:offsetHeight={height}>
<Chart {width} {height} />
</div>
display: inline
元素没有宽度或高度(具有 ‘intrinsic’ 尺寸的元素除外,如<img>
和<canvas>
),并且无法通过ResizeObserver
观察到。你需要将这些元素的display
样式更改为其他样式,例如inline-block
。¥[!NOTE]
display: inline
elements do not have a width or height (except for elements with ‘intrinsic’ dimensions, like<img>
and<canvas>
), and cannot be observed with aResizeObserver
. You will need to change thedisplay
style of these elements to something else, such asinline-block
.
bind:this
bind:this={dom_node}
要获取对 DOM 节点的引用,请使用 bind:this
。该值将为 undefined
,直到组件安装完成 — 换句话说,你应该在效果或事件处理程序中读取它,但不要在组件初始化期间读取它:
¥To get a reference to a DOM node, use bind:this
. The value will be undefined
until the component is mounted — in other words, you should read it inside an effect or an event handler, but not during component initialisation:
<script>
/** @type {HTMLCanvasElement} */
let canvas;
$effect(() => {
const ctx = canvas.getContext('2d');
drawStuff(ctx);
});
</script>
<canvas bind:this={canvas} />
组件还支持 bind:this
,允许你以编程方式与组件实例交互。
¥Components also support bind:this
, allowing you to interact with component instances programmatically.
<ShoppingCart bind:this={cart} />
<button onclick={() => cart.empty()}> Empty shopping cart </button>
<script>
// All instance exports are available on the instance object
export function empty() {
// ...
}
</script>
<script lang="ts">
// All instance exports are available on the instance object
export function empty() {
// ...
}
</script>
bind:组件的属性(bind:property for components)
¥bind:property for components
bind:property={variable}
你可以使用与元素相同的语法绑定到组件 props。
¥You can bind to component props using the same syntax as for elements.
<Keypad bind:value={pin} />
虽然 Svelte props 在没有绑定的情况下是反应性的,但默认情况下该反应性仅向下流入组件。使用 bind:property
允许对组件内部的属性的更改流回到组件之外。
¥While Svelte props are reactive without binding, that reactivity only flows downward into the component by default. Using bind:property
allows changes to the property from within the component to flow back up out of the component.
要将属性标记为可绑定,请使用 $bindable
符文:
¥To mark a property as bindable, use the $bindable
rune:
<script>
let { readonlyProperty, bindableProperty = $bindable() } = $props();
</script>
将属性声明为可绑定意味着它可以使用 bind:
来使用,而不是必须使用 bind:
来使用。
¥Declaring a property as bindable means it can be used using bind:
, not that it must be used using bind:
.
可绑定属性可以具有后备值:
¥Bindable properties can have a fallback value:
<script>
let { bindableProperty = $bindable('fallback value') } = $props();
</script>
此后备值仅在属性未绑定时适用。当属性被绑定并且存在后备值时,父级应该提供除 undefined
之外的值,否则会引发运行时错误。这可以防止难以推断的情况,即不清楚应该应用哪个值。
¥This fallback value only applies when the property is not bound. When the property is bound and a fallback value is present, the parent is expected to provide a value other than undefined
, else a runtime error is thrown. This prevents hard-to-reason-about situations where it’s unclear which value should apply.