bind
資料通常是從父元件向下流向子元件。 bind:
指令允許資料反向流動,從子元件流向父元件。
一般語法為 bind:property={expression}
,其中 expression
是一個左值(即變數或物件屬性)。當表達式是一個與屬性名稱相同的識別符號時,我們可以省略表達式 — 換句話說,它們是等價的。
<input bind:value={value} />
<input bind:value />
Svelte 會建立一個事件監聽器來更新綁定的值。如果元素已經有一個相同事件的監聽器,則該監聽器會在綁定值更新之前觸發。
大多數綁定都是雙向的,這表示對值的變更會影響元素,反之亦然。少數綁定是唯讀的,這表示變更它們的值不會對元素產生任何影響。
<input bind:value>
<input>
元素上的 bind:value
指令會綁定輸入的 value
屬性
<script>
let message = $state('hello');
</script>
<input bind:value={message} />
<p>{message}</p>
如果是數值輸入(type="number"
或 type="range"
),則該值會被強制轉換為數字 (範例)
<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
並且是表單的一部分,則當表單重設時,它會還原為該值,而不是空字串。請注意,對於初始渲染,綁定的值優先,除非它是 null
或 undefined
。
<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} />
Accept terms and conditions
</label>
從 5.6.0 版本開始,如果 <input>
具有 defaultChecked
屬性並且是表單的一部分,則當表單重設時,它會還原為該值,而不是 false
。請注意,對於初始渲染,綁定的值優先,除非它是 null
或 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
。
<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)" />
bind:group
僅在輸入位於同一個 Svelte 元件中時才有效。
<input bind:files>
在具有 type="file"
的 <input>
元素上,您可以使用 bind:files
來取得選取檔案的 FileList
。當您想要以程式方式更新檔案時,您始終需要使用 FileList
物件。目前無法直接建構 FileList
物件,因此您需要建立新的DataTransfer
物件並從那裡取得 files
。
<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
物件並新增您要保留的檔案。
DataTransfer
可能在伺服器端 JS 執行階段不可用。將綁定到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">Rice</option>
<option value="Beans">Beans</option>
<option value="Cheese">Cheese</option>
<option value="Guac (extra)">Guac (extra)</option>
</select>
當 <option>
的值與其文字內容相符時,可以省略該屬性。
<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
,則它會優先。
<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] 元素相同的所有綁定,外加唯讀的 videoWidth
和 videoHeight
綁定。
<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 綁定
具有 contenteditable
屬性的元素支援以下綁定
innerText
和textContent
之間存在細微差異。
<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
— 換句話說,您應該在效果或事件處理常式內部讀取它,而不是在元件初始化期間讀取。
<script>
/** @type {HTMLCanvasElement} */
let canvas;
$effect(() => {
const ctx = canvas.getContext('2d');
drawStuff(ctx);
});
</script>
<canvas bind:this={canvas} />
元件也支援 bind:this
,允許您以程式方式與元件實例互動。
<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>
元件的 bind:property
bind:property={variable}
您可以使用與元素相同的語法來綁定元件屬性。
<Keypad bind:value={pin} />
雖然 Svelte 屬性在沒有綁定的情況下也是響應式的,但該響應性預設只向下流動到元件中。使用 bind:property
允許從元件內部對屬性進行的變更向上流出元件。
要將屬性標記為可綁定,請使用 $bindable
符文。
<script>
let { readonlyProperty, bindableProperty = $bindable() } = $props();
</script>
將屬性宣告為可綁定表示它可以透過 bind:
使用,而不是必須透過 bind:
使用。
可綁定屬性可以有回退值
<script>
let { bindableProperty = $bindable('fallback value') } = $props();
</script>
此回退值僅在屬性未綁定時適用。當屬性已綁定且存在回退值時,父元件預期提供一個不是 undefined
的值,否則會擲回執行階段錯誤。這可以防止難以理解的情況,在這種情況下,不清楚應該套用哪個值。