這是〈Svelte 從小白到入門〉系列的第十四集,各集連結如下:


Svelte 內建了一系列特有的元素,各有不同功效,本集一一認識。

<svelte:self>

<svelte:self> 讓元件可以在體內調用自己同一個元件。

下面的例子是一個樹狀的資料夾結構,而一個 Folder 元件內有可能要調用另一個 Folder 元件,所以在 Folder 元件內我們可以看到有用 <svelte:self {...file}> 調用另一個 Folder 元件:

<svelte:component>

<svelte:component> 讓我們得以動態調用元件。

下面的例子裡,有紅色與綠色元件,要調用哪個顏色是根據用戶的選擇而動態改變的,除了用一系列的 if 做抉擇之外,也可以用更簡潔的 <svelte:component> 來達成:

在範例中,<svelte:component this={selected.component}>this 用於聲明要調用的元件。

<svelte:window>

因為瀏覽器的 window 物件在 Svelte 建置期間是不存在的,所以想要對瀏覽器的 window 做的事,得改用 <svelte:window>

下面的例子裡,我們想要對 window 監聽按鍵,所以我們用 <svelte:window on:keydown={handleKeydown}/> 來達成:

<svelte:window> 也可以做數據綁定,可用的屬性如下:

  • innerWidth
  • innerHeight
  • outerWidth
  • outerHeight
  • scrollX
  • scrollY
  • online — an alias for window.navigator.onLine

除了 scrollXscrollY 以外,皆為唯讀屬性。

下面是綁定 scrollY 的示例:

<svelte:body>

<svelte:window> 類似,想對 document.body 做的事在 Svelte 請改用 <svelte:body>

下面是監聽滑鼠事件的範例:

<svelte:head>

與前面類似,想要塞入 <head> 的標籤請改用 <svelte:head>

<svelte:options>

<svelte:options> 用於設定 Svelte 編譯參數。

immutable 為例,下面的範例中,工項每被切換一次,就會閃一下,這主要是靠 Todo 元件內的 afterUpdate()flash() 實現,在預設的編譯行為下,點擊觸發的切換,會呼叫 toggle() 去更新 JS 的 todos 陣列,導致全體觸發 update 事件,也導致用戶點一個工項,卻是全體都閃了一下,所以我們在 todo 元件內用 <svelte:options immutable={true}/> 告訴 Svelte,每個 Todo 元件都是 immutable 的,只會被新建或刪除,不會被修改,在這樣的設定下,todos 陣列的更新只會觸發那個被「翻新」的工項的發閃,既有工項因為是 immutable 的,就不會跑 afterUpdate(),也不會閃了。

<svelte:options> 所有可用的選項如下:

  • immutable={true} — you never use mutable data, so the compiler can do simple referential equality checks to determine if values have changed
  • immutable={false} — the default. Svelte will be more conservative about whether or not mutable objects have changed
  • accessors={true} — adds getters and setters for the component’s props
  • accessors={false} — the default
  • namespace="..." — the namespace where this component will be used, most commonly “svg”
  • tag="..." — the name to use when compiling this component as a custom element

詳請請參閱 Svelte API 文件

<svelte:fragment>

<svelte:fragment> 讓我們在置入 slot 內容時,不需用一個容器元素把內容包起來。

下面的例子裡,Box 元件以 flex 布局,每個元素間距 2 em,在插入 slot 內容時,如果是用一般容器,會形成這樣的結構:

<div class="box">
	<slot name="header">No header was provided</slot>
	<p>Some content between header and footer</p>
    <div slot="footer">
        <p>All rights reserved.</p>
        <p>Copyright (c) 2019 Svelte Industries</p>
    </div>
</div>

當然編譯後的原始碼沒這麼簡單,僅是示意。

因為多了一層 <div> 所以「All rights reserved.」與「Copyright (c) 2019 Svelte Industries」之間是沒有那 2 em 間距的,所以我們可以用 <svelte:fragment> 讓容器變成「透明的」:

<div class="box">
	<slot name="header">No header was provided</slot>
	<p>Some content between header and footer</p>

        <p>All rights reserved.</p>
        <p>Copyright (c) 2019 Svelte Industries</p>

</div>

如此一來,每行文字之間都有了 2 em 的間距。

完整的範例如下: