這是〈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 從小白到入門(十七)結束與展望〉
Action
Action 是客製 Svelte 元件內 HTML 元素行為的函式,利用 Svelte 提供的機制,賦予原生的 HTML 元素具有 action 函式的特性。
自訂事件
下面我們用 action 函式賦予 HTML 元素額外的事件特性,當原生的 HTML 事件不足以表示我們的元件邏輯時,可以用 action 自行定義元素的事件,當然也包括對原生事件的二次封裝,使元素與事件在邏輯上或語意上更加一致。
下面的橘色方塊,可以被滑鼠拖移(pan),放開後又會彈回中間,為此我們定義了一系列的 pan 事件在 pannable.js 裡,引用 pannable.js 後在 HTML 區域以 use:pannable
的語句使其作用在橘色方塊的 <div>
上,爾後橘色方塊就可以以 on:
語句聲明一系列 pan 事件所要觸發的函式:
打開 pannable.js 看看:
pnnable(node)
被餵了個node
,這是 action 函式的約定作法。因為在 HTML 內我們是對橘色方塊的<div>
使用use:pannable
,所以這裡的node
就是那個橘色方塊- 當滑鼠按下時,因為
node.addEventListener('mousedown', handleMousedown)
,觸發了handleMousedown()
handleMousedown()
裡面又監聽了mousemove
與mouseup
兩個原生事件,並觸發相對的函式- 在那些自訂的函式內,我們用
node.dispatchEvent(new CustomEvent())
語句來建構與對外分派自訂事件 - 最後的
destroy()
則是當node
被銷毀時會被觸發的函式
當自訂事件作用在橘色方塊後,就可以用 on:
語句聲明這些自訂的 pan 事件所要觸發的函式。
Action 參數
要為一個 action 添加參數,語法與前面兩集提過的 transition、animation 一樣:
<button use:longpress="{duration}">press and hold</button>
如果要餵兩個參數,則把他們包成 JS 物件的形式:
<button use:longpress="{{duration, spiciness}}">
press and hold
</button>
下面的範例中,滑桿的秒數會影響按鈕長按行為的秒數。
我們定義一個 duration
,並將它與滑桿的值做綁定,再將 duration
作為參數餵給 longpress
action:
在 longpress.js 內的結構,與前一個範例差不多,但注意到 retren
內多了一個 update()
,此函式用於當 use:longpress="{duration}"
的 {duration}
變化時 Svelte 會自動執行 update()
,也就是說,當 update()
不存在時,duration
是不會自動更新的,這很不 reactivity…。
小結
Action 是 Svelte 提供給我們自訂 HTML 元素行為的機制,它的聲明語法與 transition、animation 相似:
<button use:longpress="{{duration, spiciness}}">
而所謂的 Action 本身是一個有固定格式的函式:
- 此函式接受一個
node
參數,node
將會是調用此 action 的 HTML 元素,以上例來說就會是<button>
- 當 action 的參數在外部被異動時,Svelte 會自動呼叫 action 內的
update()
,我們可以在update()
內為參數做更新 - 當
node
被刪除時,Svelte 會自動呼叫 action 內的destroy()
,我們可以將不必要的物件或邏輯刪除