這是〈Svelte 從小白到入門〉系列的第十四集,各集連結如下:
- 〈Svelte 從小白到入門(一)元件、事件、Reactivity〉
- 〈Svelte 從小白到入門(二)Props、邏輯、迴圈、Await〉
- 〈Svelte 從小白到入門(三)事件〉
- 〈Svelte 從小白到入門(四)數據綁定〉
- 〈Svelte 從小白到入門(五)生命週期〉
- 〈Svelte 從小白到入門(六)Store〉
- 〈Svelte 從小白到入門(七)動態效果〉
- 〈Svelte 從小白到入門(八)進出場效果〉
- 〈Svelte 從小白到入門(九)動畫效果〉
- 〈Svelte 從小白到入門(十)Action〉
- 〈Svelte 從小白到入門(十一)CSS Class〉
- 〈Svelte 從小白到入門(十二)Slot〉
- 〈Svelte 從小白到入門(十三)Context〉
- 〈Svelte 從小白到入門(十四)Svelte 的特殊元素〉
- 〈Svelte 從小白到入門(十五)Module Context〉
- 〈Svelte 從小白到入門(十六)Debugging〉
- 〈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 forwindow.navigator.onLine
除了 scrollX
、scrollY
以外,皆為唯讀屬性。
下面是綁定 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 changedimmutable={false}
— the default. Svelte will be more conservative about whether or not mutable objects have changedaccessors={true}
— adds getters and setters for the component’s propsaccessors={false}
— the defaultnamespace="..."
— 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 的間距。
完整的範例如下: