基本標記
Svelte 元件中的標記可以被視為 HTML++。
標籤
小寫的標籤,像是 <div>
,表示一個普通的 HTML 元素。大寫的標籤或使用點符號的標籤,像是 <Widget>
或 <my.stuff>
,表示一個元件。
<script>
import Widget from './Widget.svelte';
</script>
<div>
<Widget />
</div>
元素屬性
預設情況下,屬性的行為與其 HTML 對應物完全相同。
<div class="foo">
<button disabled>can't touch this</button>
</div>
如同在 HTML 中,值可以不用加上引號。
<input type=checkbox />
屬性值可以包含 JavaScript 表達式。
<a href="page/{p}">page {p}</a>
或者它們可以是 JavaScript 表達式。
<button disabled={!clickable}>...</button>
如果布林屬性的值為 truthy,則會包含在元素中,如果為 falsy,則會排除。
除非屬性的值為 nullish (null
或 undefined
),否則所有其他屬性都會被包含在內。
<input required={false} placeholder="This input field is not required" />
<div title={null}>This div has no title attribute</div>
將單一表達式加上引號並不會影響值的解析方式,但在 Svelte 6 中,它會導致值被強制轉換為字串。
<button disabled="{number !== 42}">...</button>
當屬性名稱和值匹配時 (name={name}
),它們可以用 {name}
來取代。
<button {disabled}>...</button>
<!-- equivalent to
<button disabled={disabled}>...</button>
-->
元件屬性 (props)
按照慣例,傳遞給元件的值稱為屬性 (properties) 或 props,而不是 DOM 的特性attributes。
如同元素一樣,name={name}
可以用 {name}
簡寫取代。
<Widget foo={bar} answer={42} text="hello" />
展開屬性 (Spread attributes) 允許一次將多個屬性或屬性傳遞給元素或元件。
一個元素或元件可以有多個展開屬性,並與一般的屬性穿插在一起。
<Widget {...things} />
事件
可以透過在以 on
開頭的元素上添加屬性來監聽 DOM 事件。例如,要監聽 click
事件,請在按鈕上添加 onclick
屬性。
<button onclick={() => console.log('clicked')}>click me</button>
事件屬性是區分大小寫的。onclick
監聽 click
事件,而 onClick
監聽 Click
事件,兩者是不同的。這確保您可以監聽包含大寫字母的自定義事件。
因為事件只不過是屬性,所以屬性的規則同樣適用。
- 您可以使用簡寫形式:
<button {onclick}>點擊我</button>
- 您可以展開它們:
<button {...thisSpreadContainsEventAttributes}>點擊我</button>
在時序上,事件屬性總是在綁定的事件之後觸發 (例如,oninput
總是在更新 bind:value
之後觸發)。在底層,某些事件處理程序是直接使用 addEventListener
附加的,而其他則是被委派 (delegated) 的。
當使用 ontouchstart
和 ontouchmove
事件屬性時,為了獲得更好的效能,處理程式是 被動 (passive) 的。這大大提高了響應速度,因為它允許瀏覽器立即捲動文件,而不是等待查看事件處理程式是否調用 event.preventDefault()
。
在極少數需要阻止這些事件預設行為的情況下,您應該改用 on
(例如在 action 內部)。
事件委派
為了減少記憶體佔用並提高效能,Svelte 使用一種稱為事件委派的技術。這表示對於某些事件(請參閱下面的清單),應用程式根目錄中的單一事件監聽器會負責執行事件路徑上的任何處理程式。
有幾個需要注意的地方。
- 當您使用委派的監聽器手動分派事件時,請務必設定
{ bubbles: true }
選項,否則它將無法到達應用程式根目錄。 - 當直接使用
addEventListener
時,請避免調用stopPropagation
,否則事件將無法到達應用程式根目錄,並且不會調用處理程式。同樣地,手動在應用程式根目錄內添加的處理程式將在以宣告方式在 DOM 中更深處添加的處理程式 (例如使用onclick={...}
) 之前執行,無論是在捕獲階段還是冒泡階段。由於這些原因,最好使用從svelte/events
導入的on
函數,而不是addEventListener
,因為它將確保保留順序並正確處理stopPropagation
。
下列事件處理程式會被委派:
beforeinput
click
change
dblclick
contextmenu
focusin
focusout
input
keydown
keyup
mousedown
mousemove
mouseout
mouseover
mouseup
pointerdown
pointermove
pointerout
pointerover
pointerup
touchend
touchmove
touchstart
文字表達式
可以使用大括號將 JavaScript 表達式包含為文字。
{expression}
大括號可以透過使用其 HTML 實體字串包含在 Svelte 範本中:{
、{
或 {
代表 {
,而 }
、}
或 }
代表 }
。
如果您使用正規表達式 (RegExp
) 字面表示法,您需要將其包在括號中。
<h1>Hello {name}!</h1>
<p>{a} + {b} = {a + b}.</p>
<div>{(/^[A-Za-z ]+$/).test(value) ? x : y}</div>
該表達式將被字串化並轉義,以防止程式碼注入。如果您想呈現 HTML,請改用 {@html}
標籤。
{@html potentiallyUnsafeHtmlString}
請確保您要麼轉義傳遞的字串,要麼只使用您可以控制的值來填充它,以防止 XSS 攻擊。
註解
您可以在元件內使用 HTML 註解。
<!-- this is a comment! --><h1>Hello world</h1>
以 svelte-ignore
開頭的註解會禁用下一段標記的警告。通常,這些是輔助功能警告;請確保您禁用它們是有充分理由的。
<!-- svelte-ignore a11y-autofocus -->
<input bind:value={name} autofocus />
您可以新增一個以 @component
開頭的特殊註解,當滑鼠停留在其他檔案中的元件名稱上時,該註解會顯示。
<!--
@component
- You can use markdown here.
- You can also use code blocks here.
- Usage:
```html
<Main name="Arethra">
```
-->
<script>
let { name } = $props();
</script>
<main>
<h1>
Hello, {name}
</h1>
</main>