[Alpine.js] 指示詞 (Directive)應用之二

標籤: Alpine.js javascript

x-on

範例:

<button x-on:click="foo = 'bar'"></button>

結構:

<button x-on:[事件]="[運算式]"></button>

 

x-on 將事件監聽器附加至宣告 x-on 的元素上。當發出該事件後,執行設定為該事件值的對應 JavaScript 運算式,可以簡寫成 @。

若在該運算式中有修改任何資料,則其他「繫結 Bind」該資料元素屬性也會一併更新。

 

也可以指定一個 JavaScript 函式名稱

範例:

<button x-on:click="myFunction"></button>

與以下程式碼相同:

<button x-on:click="myFunction($event)"></button>

 

keydown 修飾詞

範例:

<input type="text" x-on:keydown.escape="open = false">

可以將按鍵附加到 x-on:keydown 指示詞後面來指定要監聽的按鍵。請注意,該修飾詞使用的是 - 號分隔命名 (kebab-cased) 版本的 Event.key 值。

如: enter, escape, arrow-up, arrow-down

也可以監聽使用系統修飾詞的按鍵組合,如: x-on:keydown.cmd.enter="foo"

.away 修飾詞

範例:

<div x-on:click.away="showModal = false"></div>

當有 .away 修飾詞時,將只會在由非該元素或該元素子節點的其他元素發出事件時執行事件處理常式。

適合用在讓使用者點擊元件外面來關閉下拉選單與強制回應視窗時隱藏這些元件等情況。

 

.prevent 修飾詞

範例:

<input type="checkbox" x-on:click.prevent>

在事件監聽器加上 .prevent 會在觸發的事件上呼叫 preventDefault。在上述範例中,使用 .prevent 則代表該多選框在使用者點擊後不會被實際選中。

 

.stop 修飾詞

範例:

<div x-on:click="foo = 'bar'"><button x-on:click.stop></button></div>

在事件監聽器加上 .stop 會在觸發的事件上呼叫 stopPropagation。在上述範例中,使用 .stop 則代表「click」事件觸發之後不會從底部 Bubble 到外層的 <div> 。換句話來說,使用者點擊按鈕 (Button) 後, foo 的值不會被設為 'bar'

 

.self 修飾詞

範例:

<div x-on:click.self="foo = 'bar'"><button></button></div>

在事件監聽器加上 .self 則只會在 $event.target 是該元素的時候才觸發監聽器。在上述範例中,則表示從按鈕 Bubble 到外層 <div> 上來的「click」事件 不會 執行監聽器。

 

.window 修飾詞

範例:

<div x-on:resize.window="isOpen = window.outerWidth > 768 ? false : open"></div>

在事件監聽器加上 .window 會將監聽器安裝到全域的 window 物件中,而不是宣告該監聽器的 DOM 物件上。適合用在當有其他東西修改了 window 而需要修改元件狀態的時候,如縮放事件。在本例中,當視窗調整為大於 768 像素寬時,程式會關閉強制回應視窗或下拉選單,否則會繼續維持原本的狀態。

 

.once 修飾詞

範例:

<button x-on:mouseenter.once="fetchSomething()"></button>

在事件監聽器加上 .onece 則可以確保只會呼叫一次事件監聽器。適合用來做一些只需要做一次就好的事,如取得 HTML 部分等。

 

.passive 修飾詞

範例:

<button x-on:mousedown.passive="interactive = true"></button>

在事件監聽器加上 .passive 修飾詞則可讓監聽器成為被動,也就表示在所有處理的事件上 preventDefault() 都將不會有任何作用。可以用在如提升觸控裝置上的滾動效能等目的。

 

.debounce 修飾詞

範例:

<input x-on:input.debounce="fetchSomething()">

.debounce 修飾詞可以試事件監聽器「消除彈跳 (Debouce)」。也就是說,該處理常式會等到上一個事件觸發後的一段時間後才執行。當處理常式準備好可執行後,則會執行上一個處理常式呼叫。

預設的消除彈跳「等待」時間為 250 毫秒。

若要自定等待事件,則可使用如下方法指定:

<input x-on:input.debounce.750="fetchSomething()">
<input x-on:input.debounce.750ms="fetchSomething()">

 

.camel 修飾詞

範例:

<input x-on:event-name.camel="doSomething()">

使用 .camel 修飾詞來監聽以駝峰命名法命名的事件。在上述例子中,元素觸發 eventName 事件後會執行該運算式。

 

x-model

範例:

<input type="text" x-model="foo">

結構:

<input type="text" x-model="[資料項目]">

 

x-model 可用來在元素加上「雙向資料繫結 (Two-way Data Binding)」。也就是說,輸入元素的值會保持與元件資料項目的值同步。

用起來就跟 vue.js 一樣:

 

.debounce 修飾詞 

範例:

<input x-model.debounce="search">

debounce 修飾詞可以在數值更新上加上「消除彈跳 (Debounce)」。也就是說,從上一次事件觸發之後的一段時間之後才會呼叫事件處理常式。當處理常式可呼叫後,才會執行上一個處理常式呼叫。

預設的消除彈跳「等待」時間為 250 毫秒。

若要自定等待時間,則可用下列方式指定:

<input x-model.debounce.750="search">
<input x-model.debounce.750ms="search">

 

x-text

範例:

<span x-text="foo"></span>

結構:

<span x-html="[運算式]">

x-text 類似 x-bind ,但更新的不是元素的屬性,而是 innerText

 

x-html

範例:

<span x-html="foo"></span>

結構:

<span x-html="[運算式]">

x-text 類似 x-bind ,但更新的不是元素的屬性,而是 innerHTML

 

x-ref

範例:

<div x-ref="foo"></div><button x-on:click="$refs.foo.innerText = 'bar'"></button>

結構:

<div x-ref="[參照名稱]"></div><button x-on:click="$refs.[ref name].innerText = 'bar'"></button>

x-ref 提供從元件上取得原始 DOM 元素的簡便方法。只要在元素上設定 x-ref 屬性,就可以在所有事件處理常式中通過 $refs 物件來取得該元素。

除了設定 ID 並在各個地方使用 document.querySelector,使用 x-ref 可作為替代方法。

 

x-if

範例:

<template x-if="true"><div>一些元素</div></template>

結構:

<template x-if="[運算式]"><div>一些元素</div></template>

 

但遇到一些 x-show 不合用的情況 (x-show 會在表達式為 false 時將元素設為 display: none),則可以使用 x-if 來將元素完全從 DOM 中移除。

但要注意,x-if 必須要用在 <template></template> 標籤上,因為 Alpine 不使用虛擬 DOM。這種實作方式可保持 Alpine 簡陋,並使用真的 DOM 來處理動態 (Magic) 的部分。

備註:使用 x-if<template></template> 標籤中必須只能有單一根元素。

備註:如果要在 svg 標籤中使用 template,則需要在 Alpine.js 初始化前執行一段 polyfill

 

 

x-for

範例:

<template x-for="item in items" :key="item">
    <div x-text="item"></div>
</template>

x-for 適用於需要為陣列中每個項目建立新 DOM 節點的情況。用法看起來應該跟 Vue 中的 v-for 類似,但唯一不同的地方就是要放在 template 標籤上而不是一般的 DOM 元素。

若需要存取目前迭代的索引,則可使用下列語法:

<template x-for="(item, index) in items" :key="index">
    <!-- 若有需要也可以在迭代中參照「index」。 -->
    <div x-text="index"></div>
</template>

備註:使用 x-for<template></template> 標籤中必須只能有單一根元素。

備註:如果要在 svg 標籤中使用 template,則需要在 Alpine.js 初始化前執行一段 polyfill

 

巢狀嵌套 x-for

可以嵌套多層 x-for 迴圈,但每個迴圈都 必須 放在一個元素內,如:

<template x-for="item in items">
    <div>
        <template x-for="subItem in item.subItems">
            <div x-text="subItem"></div>
        </template>
    </div>
</template>

 

x-transition

範例:

<div
    x-show="open"
    x-transition:enter="transition ease-out duration-300"
    x-transition:enter-start="opacity-0 transform scale-90"
    x-transition:enter-end="opacity-100 transform scale-100"
    x-transition:leave="transition ease-in duration-300"
    x-transition:leave-start="opacity-100 transform scale-100"
    x-transition:leave-end="opacity-0 transform scale-90"
>...</div>

 

<template x-if="open">
    <div
        x-transition:enter="transition ease-out duration-300"
        x-transition:enter-start="opacity-0 transform scale-90"
        x-transition:enter-end="opacity-100 transform scale-100"
        x-transition:leave="transition ease-in duration-300"
        x-transition:leave-start="opacity-100 transform scale-100"
        x-transition:leave-end="opacity-0 transform scale-90"
    >...</div>
</template>

 上述範例使用了 Tailwind CSS 的 Class 

 

 

Alpine 中提供了 6 種不同的變換指示詞,可用於在元素變換的「hidden 隱藏」與「shown 顯示」狀態間的各個階段套用 Class。這些指示詞可用在 x-show x-if 上。

這些行為都與 VueJS 的 transition 指示詞很類似,但不同的地方則是使用了不同的名稱:

指示詞 說明
:enter 套用於整個 Enter 階段。
:enter-start 在元素插入前新增,並在元素插入的 1 幀後刪除。
:enter-end 在元素插入後 (與 enter-start 刪除同時) 1 幀時新增,變換或動畫結束時刪除。
:leave 套用於整個 Leave 階段。
:leave-start 在 Leave 變換觸發後立刻新增、並在 1 幀後刪除。
:leave-end 在 Leave 變換觸發後 (與 leave-start 刪除同時) 1 幀新增,並在變換或動畫結束時刪除。

 

x-spread

範例:

<div x-data="dropdown()">
    <button x-spread="trigger">開啟下拉選單</button>

    <span x-spread="dialogue">下拉選單內容</span>
</div>

<script>
    function dropdown() {
        return {
            open: false,
            trigger: {
                ['@click']() {
                    this.open = true
                },
            },
            dialogue: {
                ['x-show']() {
                    return this.open
                },
                ['@click.away']() {
                    this.open = false
                },
            }
        }
    }
</script>

x-spread 可用來將元素的 Alpine 繫結截取到可重複使用的元素中。

元素的索引鍵為指示詞 (可以是任何指示詞,包含修飾詞),而元素值則為由 Alpine 取值的回呼函式。

備註:x-spread 唯一要注意的就是與 x-for 搭配使用的情況。當被「spread」的指示詞是 x-for,則回呼內回傳的應該要是運算式字串。如: ['x-for']() { return 'item in items' }.

 

x-cloak

範例:

<div x-data="{}" x-cloak></div>

x-cloak 屬性會在 Alpine 初始化後從元素上移除。可以用來隱藏還未初始化的 DOM 元素。通常使用下列全域樣式:

<style>
    [x-cloak] { display: none; }
</style>