bahasa Indonesia
https://alpinejs.dev/start-here
Daftar Isi
Start Here ........................................................................................................................................................ 1
Essentials ....................................................................................................................................................... 17
Installation ............................................................................................................................................... 17
State ............................................................................................................................................................ 18
Templating .............................................................................................................................................. 21
Event .......................................................................................................................................................... 26
Lifecycle ................................................................................................................................................... 28
Directives ....................................................................................................................................................... 31
x-data ......................................................................................................................................................... 31
x-init ........................................................................................................................................................... 34
x-show ...................................................................................................................................................... 36
x-bind.........................................................................................................................................................37
x-on ............................................................................................................................................................. 41
x-text.......................................................................................................................................................... 48
x-html ....................................................................................................................................................... 49
x-modelable ........................................................................................................................................ 54
x-for ............................................................................................................................................................ 54
x-transition ............................................................................................................................................ 56
x-effect..................................................................................................................................................... 59
x-ignore ................................................................................................................................................... 60
x-ref ............................................................................................................................................................ 60
x-cloak....................................................................................................................................................... 61
x-teleport ................................................................................................................................................ 62
x-id .............................................................................................................................................................. 65
Magics ........................................................................................................................................................... 66
i
$el ................................................................................................................................................................ 66
$refs ........................................................................................................................................................... 66
$store ........................................................................................................................................................ 66
$watch ..................................................................................................................................................... 67
$dispatch ............................................................................................................................................... 69
$nextTick ................................................................................................................................................. 70
$root............................................................................................................................................................. 71
$data .......................................................................................................................................................... 72
$id ................................................................................................................................................................. 72
Globals .......................................................................................................................................................... 76
Alpine.data ............................................................................................................................................ 76
Alpine.store ........................................................................................................................................... 79
Alpine.bind .............................................................................................................................................. 81
Plugin.............................................................................................................................................................. 83
x-intersect.............................................................................................................................................. 86
Focus Plugin.......................................................................................................................................... 94
Advanced.................................................................................................................................................... 110
ii
Start Here
Buat sebuah berkas (file) HTML kosong dimanapun di komputer anda
dengan nama seperti: i-love-alpine.html
buka file di peramban web, jika anda melihat I ❤️ Alpine Anda siap
untuk berderu!
Kini Anda telah memiliki set up untuk bermain, Ayo lihat pada tiga contoh
praktek sebagai dasar untuk mengajari Anda dasar-dasar Alpine. Pada
akhir latihan ini, Anda seharusnya lebih dari lebih dari cukup untuk mulai
membangun aplikasi anda sendiri. Ayo.
<span x-text="count"></span>
</div>;
1
Sekarang Anda dapat melihat dengan 3 bits dari Alpine ditaburi ke dalam
HTML ini, ini kita telah membuat sebuah komponen “counter”. Ayo kita
apa yang terjadi secara singkat:
Declaring data
<div x-data="{ count: 0 }"></div>
Semua di dalam Alpine dimulai dengan direktif x-data. Di dalam x-data , di
JavaScript biasa, anda mendeklarasikan sebuah objek data yang yang
akan dan dilacek oleh Alpine.
Setiap properti di dalam objek ini akan dibuat tersedia untuk direktif lain di
dalam elemen HTML ini. Sebagai tambahan, ketika salah satu properti
berubah, semua yang bergantung padanya akan berubah juga.
Ayo lihat pada x-on dan lihat bagaimana x-on dapat diakses
dan mengubah properti count dari atas:
Reacting to changes
<h1 x-text="count"></h1>;
x-text adalah sebuah direktif Alpine yang Anda dapat gunakan untuk
mengatur konten teks dari elemen ke hasil dari ekspresi JavaScript.
2
Pada kasus ini, kita memberitahu Alpine untuk selalu memastikan konten
dari tag h1 mencerminkan nilai dari properti count.
jika belum jelas, x-text, seperti kebanyakan direktif menerima ekspresi
JavaScript polos atau biasa sebagai sebuah argumen. Sebagai
contoh, Anda bisa mengatur konten ke x-text="count * 2" dan teks konten
dari h1 kini akan selalu dua kali dari nilai count.
Kini Anda telah melihat beberapa Apa fungsi dasar, Ayo lanjutkan dan
lihat pada direktif Alpine yang penting: x-show, dengan membangun
sebuah komponen “dropdown” yang dibuat secara perlahan.
Directif x-data dan x-on dan harusnya familiar dengan anda dari contoh
sebelumnya jadi kita akan melewati penjelasan ini.
Toggling element
3
anda akan menyadari sesuatu yang baru pada contoh ini .outside.
Banyak direktif di Alpine menerima modifier yang disambung (chained) ke
akhir direktif dan dipisahkan dengan titik.
Ini merupakan sebuah helper yang dibangun ke Alpine karena ini umum
dibutuhkan dan diimplementasikan ini dengan tangan sangat
menjengkelkan dan kompleks.
<div
x-data="{
search: '',
get filteredItems() {
return this.items.filter(
i => i.startsWith(this.search)
)
}
}"
>
<input x-model="search" placeholder="Search...">
<ul>
<template x-for="item in filteredItems" :key="item">
<li x-text="item"></li>
</template>
</ul>
</div>
Secara bawaan semua “items” (foo, bar, dan baz) akan ditampilkan di
halaman tapi anda dapat menyaringnya dengan mengetik ke dalam
4
input text. Ketika anda menulis, daftar item akan berubah mencerminkan
Apa yang anda cari.
Kini ini ada banyak hal yang terjadi di sini, ayo lihat potongan ini bagian
demi bagian.
Hal pertama yang ingin saya tekankan adalah bahwa x-data kini lebih
banyak dari sebelumnya. Untuk memudahkan menulis dan membaca,
kita memecahnya ke dalam beberapa baris di HTML kita. Ini sepenuhnya
opsional dan kita akan berbicara lebih banyak tentang bagaimana
menghindari masalah ini bersama tapi untuk sekarang kita akan
membiarkan semua dari javascript ini secara langsung di HTML.
Binding to inputs
anda akan menyadari sebuah directive baru yang belum Anda lihat
sebelumnya: x-model
x-model digunakan untuk “bind” (mengikat ) nilai dari sebuah elemen input
dengan properti data search dari x-data="{ search: '', ... }" pada kasus
kita.
Ini berarti kapanpun nilai berubah nilai dari “search” akan berubah
mencerminkannya.
Lanjut sedikit, aku lebih suka menarik perhatian anda ke items dan
filteredItems properti dari direktif x-data.
{
...
items: ['foo', 'bar', 'baz'],
get filteredItems() {
5
return this.items.filter(
i => i.startsWith(this.search)
)
}
}
items properti harusnya sudah cukup jelas. Di sini ini kita mengatur nilai
items ke array JavaScript dari 3 item berbeda (foo, bar, and baz).
Ini sangat diterima untuk melupakan get dan pakai method ini saja yang
dapat anda ada panggil dari template, tapi beberapa lebih suka
penulisan yang lebih baik dari getter.
Sekarang lihat ke dalam getter filteredItems dan pastikan kita pahami apa
yang terjadi di sana:
6
Karena Alpine adalah sebuah framework “reaktif”. Kapanpun nilai dari
this.search berubah, bagian dari template yang menggunakan
filteredItems otomatis diperbarui.
Looping Elements
Kini kita telah mengerti data bagian dari komponen kita, ayo pahami apa
yang terjadi di dalam template yang memungkinkan kita untuk melakukan
pengulangan (loop) melalui filteredItems di halaman.
<ul>
<li x-text="item"></li>
</template>
</ul>;
Hal pertama yang disadari disini adalah direktif x-for. Ekspresi x-for
mengambil bentuk berikut [item] in [items] ketika [item] dari data array
manapun, dan [item] adalah nama variabel yang akan ditugaskan
sebagai sebuah iterasi di dalam pengulangan.
Recap
Jika anda sampai sejauh ini, anda telah mengetahui direktif berikut
didalam Alpine:
x-data
x-on
x-text
x-show
7
x-model
x-for
Happy coding!
8
Upgrade from V2
Di bawah ini merupakan panduan lengkap dari banyak perubahan dan
didalam Alpine versi 3 tapi jika anda lebih suka sesuatu yang lebih hidup
anda dapat meninjau semua perubahan serta fitur baru di versi 3 dengan
menonton Alpine d 2021 itu future of Alpine keynote:
https://youtu.be/WixS4JXMwIQ
Perbaikan dari versi 2 ke versi 3 harusnya tidak sulit. Pada banyak kasus
TIDAK ADA yang dilakukan di kode anda untuk menggunakan versi 3. Di
bawah ini adalah daftar lengkap dari perubahan dan depresiasi dalam
urutan dari bagaimana pengguna akan berdampak pada perubahan ini:
*catat jika Anda menggunakan laravel livewire dan Alpine bersama ,untuk
menggunakan versi 3 dari Alpine, anda akan butuh meningkatkan livewire
versi 2.5.1 itu itu atau di atasnya
Breaking Changes
9
$el kini selalu merepresentasikan elemen dari ekspresi yang dieksekusi,
bukan root elemen dari komponen. Ini akan mengganti kebanyakan dari
penggunaan dari x-ref pada kasus ketika Anda masih ingin mengakses
root dari komponen anda dapat menggunakan $root contoh:
<!-- 🚫 Before -->
<div x-data>
<button @click="console.log($el)"></button>
<!-- In V2, $el would have been the <div>, now it's the <button> -->
</div>
<div x-data>
<button @click="console.log($root)"></button>
</div>
pada versi 3 Alpine akan secara otomatis memanggil method init() pada
data objek.
<!-- 🚫 Before -->
<div x-data="foo()" x-init="init()"></div>
<script>
function foo() {
return {
init() {
//
}
}
}
</script>
10
Perlu Untuk Memanggil Alpine.Start() Setelah Impor
jika anda ada telah mengimpor Alpine versi 2 dari NPM, Anda kini butuh
untuk secara manual memanggil Alpine.start() pada versi 3. Ini tidak
akan berdampak pada anda ada jika Anda menggunakan Alpine file atau
CDN dari tag <template>.
// 🚫 Before
import "alpinejs";
// ✅ After
import Alpine from "alpinejs";
window.Alpine = Alpine;
Alpine.start();
11
Ini adalah sebuah fitur yang hanya diketahui beberapa orang, apalagi
digunakan.
<template x-if.transition="open">
<div>...</div>
</template>
<div x-data="{}">
</div>
</div>
<div x-data="{}">
</div>
</div>
Alpine versi 2 mengamati sebuah nilai return dari false untuk menjalankan
preventDefault pada event ini sesuai dengan standar perilaku native inline
listener:
<div x-spread="dialogue">...</div>
</div>
<div x-bind="dialogue">...</div>
</div>
<script>
function dropdown() {
return {
open: false,
trigger: {
'x-on:click'() { this.open = ! this.open },
},
dialogue: {
'x-show'() { return this.open },
'x-bind:class'() { return 'foo bar' },
},
}
}
</script>
Gunakan life cycle event global alih-alih Alpine.deferLoadingAlpine()
<!-- 🚫 Before -->
<script>
window.deferLoadingAlpine = startAlpine => {
// Will be executed before initializing Alpine.
startAlpine()
document.addEventListener('alpine:initialized', () => {
// Will be executed after initializing Alpine.
})
</script>
14
x-ref tidak lagi mendukung binding
setelah Klik tombol semua $refs ditampilkan. Meskipun, di Alpine versi 3 ini
mungkin untuk mengakses $refs untuk elemen yang dibuat secara statis,
jadi hanya ref pertama yang dikembalikan seperti yang diharapkan
Alpine kini secara resmi tidak lagi mendukung Internet Explorer 11. Jika
anda butuh dukungan untuk IE 11 kami merekomendasikan untuk tetap
menggunakan Alpine versi 2
Deprecated APIs
15
<script>
function dropdown() {
return {
...
}
}
</script>
<script>
document.addEventListener('alpine:init', () => {
Alpine.data('dropdown', () => ({
...
}))
})
</script>
16
Essentials
Installation
Ada dua cara untuk memasukkan Alpine ke dalam proyek anda:
<html>
<head>
...
<script defer
src="https://unpkg.com/alpinejs@3.x.x/dist/cdn.min.js"></script>
</head>
...
</html>
*jangan lupa attirubte “defer” di tag <script>.
Perhatikan <script> dalam tautan CDN yang disediakan. Script ini akan
mengambil versi terakhir dari Alpine versi 3. Untuk produksi yang stabil,
direkomendasikan anda menulis versi terakhir di tautan CDN.
<script defer
src="https://unpkg.com/alpinejs@3.10.2/dist/cdn.min.js"></script>;
Jika Anda lebih suka dengan pendekatan yang lebih kuat Anda dapat
menginstal Alpine melalui NPM dan mengimpor nya ke dalam sebuah
bundel.
17
window.Alpine = Alpine;
Alpine.start();
* jika anda telah mengimpor Alpine kedalam sebuah bundel Anda harus
memastikan anda telah mendaftarkan ektensi apapun DI ANTARANYA
Ketika anda import objek global Alpin , dan ketika anda inisiasi Alpine
dengan memanggil Alpine.start().
State
State (data javascript yang Alpine awasi perubahannya) merupakan inti
dari semua yang anda lakukan di Alpine. Anda dapat menyediakan data
lokal kesebuah chunk dari HTML atau membuatnya tersedia secara global
untuk digunakan dimanapun di halaman Anda menggunakan x-data atau
Alpine.store().
Local state
Sekarang syntax Alpine lainnya atau dalam elemen ini akan dapat
mengakses open. Dan seperti yang Anda duga ketika open berubah untuk
alasan apapun semua yang bergantung padanya akan bereaksi secara
otomatis.
18
Data bersarang
Data dapat bersarang di Alpine, sebagai contoh, jika anda memiliki dua
elemen dengan Alpine data terlampir (satu didalam lainnya) Anda dapat
mengakses datanya parent dalam elemen child.
Ini mirip dengan scoping di Javascript sendiri (kode dalam sebuah fungsi
dapat mengakses variabel yang dideklarasikan di luar fungsi tersebut).
Seperti yang mungkin anda duga, jika child memeliki property data yang
cocok dengan properti parent, properti child akan diutamakan.
Meskipun ini terlihat cukup jelas bagi sebagian orang, tapi pantas untuk
disebutkan bahwa data Alpine dapat digunakan dengan di dalam elemen
yang. Sebagai contoh
Alpine tanpa-data
Re-usable data
19
Jika Anda menggunakan framework seperti Rails atau Laravel, Alpine
pertama merekomendasikan bahwa anda ekstrak seluruh block html ke
dalam template sebagian atau termasuk.
Jika untuk beberapa alasan itu tidak ideal untuk anda atau anda tidak
dalam templating environment back-end, Alpine memungkinkan anda
untuk mendaftarkan secara global dan menggunakan ulang porsi data
dari komponen menggunakan Alpine.data(...).
Alpine.data("dropdown", () => ({
open: false,
toggle() {
this.open = !this.open;
},
}));
<div x-data="dropdown">
<button @click="toggle">Expand</button>
<span x-show="open">Content...</span>
</div>
<div x-data="dropdown">
<button @click="toggle">Expand</button>
Global State
Ayo lihat contoh sederhana pertama kita akan mendaftarkan store secara
global:
20
Alpine.store("tabs", {
current: "first",
<div x-data>
<template x-for="tab in $store.tabs.items">
...
</template>
</div>
<div x-data>
<button @click="$store.tabs.current = 'first'">First Tab</button>
<button @click="$store.tabs.current = 'second'">Second Tab</button>
<button @click="$store.tabs.current = 'third'">Third Tab</button>
</div>
Templating
Text content
Kini, Alpine telah mengatur teks konten dari <h1> dengan nilai dari title
(“Start Here”). Ketika title berubah, maka content <h1> akan berubah juga.
21
<span x-text="1 + 2"></span>;
Toggling Elements
Alpine menawarkan direktif x-show dan x-if untuk toggling pada halaman
x-show
<div x-show="open">
Content...
</div>
</div>
Ini berfungsi dengan baik pada banyak kasus tapi terkadang anda
mungkin ingin menghapus dan menambahkan elemen dari DOM
seluruhnya. Ini adalah kegunaan x-if
x-if
Ini adalah toggle yang sama seperti sebelumnya tapi kali ini
menggunakan x-if alih-alih x-show.
<template x-if="open">
<div>
22
Content...
</div>
</template>
</div>
Ketika open adalah true, Alpine akan menambahkan <div> ke tag <template>
dan menghapusnya ketika open adalah false
Ini, lagi, contoh toggle sederhana, tapi kali ini dengan transisi yang telah
diterapkan:
Transition Helper
Transition CSS classes
Katakanlah anda ingin untuk membuat durasi dari transisi lebih lama,
Anda dapat secara manual menentukan durasi menggunakan modifier
.duration seperti berikut:
Jika anda ingin nilai berbeda yang khusus untuk transisi in dan out, anda
dapat menggunakan x-transition:enter dan x-transition:leave:
<div
x-show="open"
x-transition:enter.duration.500ms
x-transition:leave.duration.1000ms
>
Transition classes
jika anda butuh kontrol yang lebih halus pada awal transisi aplikasi anda,
anda dapat menerapkan CSS khusus pada fase khusus dari transisi
menggunakan syntax berikut (ini contoh menggunakan Tailwind CSS):
<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>
24
Binding attributes
Ini adalah sebuah contoh yang terikat secara dinamis dari atribut class:
<button
x-data="{ red: false }"
x-bind:class="red ? 'bg-red' : ''"
@click="red = ! red"
>
Toggle Red
</button>
kini class hidden akan ditambahkan ke elemen jika open bernilai false, dan
dihapus jika open bernilai true.
Looping Elements
25
Mirip dengan x-if , x-if harus diterapkan ke tag <template>. Secara internal,
Alpine akan menambahkan konten dari <template> setiap iterasi didalam
perulangan.
Seperti yang dapat Anda lihat variabel status baru dalam scope dari
template berulang.
Inner HTML
Sekarang, Alpine dapat mengatur konten teks dari <div> dengan elemen
<h1>Start Here</h1>. Ketika title berubah, maka content <h1> akan berubah
juga.
Event
Alpine membuatnya sederhana untuk mendengarkan browser
(peramban) event dan bereaksi pada event tersebut.
Ini adalah contoh dasar dari listening untuk klik pada tombol:
<button x-on:click="console.log('clicked')">...</button>;
sebagai sebuah alternatif, anda dapat menggunakan penulisan singkat
event jika anda suka: @. Ini sama seperti contoh sebelumnya tapi
menggunakan syntax penulisan singkat (yang akan kita gunakan untuk
mulai dari sekarang):
<button @click="...">...</button>
26
Sebagai tambahan untuk click, Anda dapat listen untuk browser event
apapun dengan nama. Sebagai contoh: @mouseenter, @keyup, dan lain-
lain...semua adalah syntax (sintaksis) yang valid.
<input @keyup.enter="...">
Anda dapat menggabungkan key modifier untuk mendengarkan
kombinasi key seperti menekan enter ketika menahan shift:
<input @keyup.shift.enter="...">
Preventing Default
<form @submit.prevent="...">...</form>
Anda dapat juga menerapkan .stop untuk mencapai hal yang sama
dengan event.stopPropagation()
27
komponen Alpine lainnya atau untuk memicu event di dalam tool di luar
dari Alpine itu sendiri.
<div x-data>
<button @click="$dispatch('foo')"></button>
</div>
Pada contoh diatas, jika kita klik tombol dalam komponen pertama, Alpine
akan dispatch event. Karena cara event bekerja di browser. Mereka
“bubble” up melalui parent element kesemua top-level “window”.
Lifecycle
Alpine memiliki beberapa teknik berbeda untuk menyambungkan bagian
berbeda dari siklus hidup. Ayo mulai dengan salah satu yang paling
berguna dan familiar dengan anda:
Element initialization
28
x-ini dapat ditambahkan ke elemen apapun di halaman dan akan
mengeksekusi JavaScript apapun yang anda panggil di dalamnya ketika
Alpine memulai menginisialisasi elemen tersebut.
Alpine.data('dropdown', () => ({
init() {
// I get called before the element using this data initializes.
}
})
seperti yang dapat Anda lihat di atas, $watch memungkinkan anda untuk
hook ke dalam perubahan data menggunakan dot-notation (notasi titik)
key. Ketika bagian data tersebut berubah Alpine akan memanggil
callback yang di oper dan berikannya nilai baru bersama dengan nilai
lama sebelum berubah.
x-effect
Alih-alih menentukan data key mana yang anda ingin pantau, x-effect
akan memanggil kode yang telah disediakan dan secara cerdas melihat
data apapun yang Alpine gunakan di dalamnya. Sekarang yang ketika 1
bagian data berubah. ekspresi x-effect akan dijalankan ulang.
29
Ini adalah kode yang sama dari contoh $watch ditulis ulang menggunakan
x-effect:
Sekarang ekspresi ini dipanggil dengan cara yang benar, dan dipanggil
ulang setiap kali open di perbarui.
menyediakan kode yang akan segera dijalankan DAN ketika data berubah
($watch bersifat “malas” tidak akan berjalan sampai data pertama
berubah)
Alpine initialization
alpine:init
document.addEventListener('alpine:init', () => {
Alpine.data(...)
})
alpine:initialized
Alpine juga menawarkan sebuah hook yang dapat anda gunakan untuk
mengeksekusi kode setelah Alpine selesai melakukan inisialisasi yang
bernama alpine:initialized:
document.addEventListener("alpine:initialized", () => {
//
});
30
Directives
x-data
Apapun di Alpine dimulai dengan direktif x-data
<div x-show="open">
Content...
</div>
</div>
jangan khawatir tentang diaktif lain pada contoh ini(@click dan x-show ),
kita akan membahasnya sebentar lagi. Sekarang, ayo fokus pada x-data
Scope
Sebagai contoh:
31
Methods
<div x-show="open">
Content...
</div>
</div>
Perhatikan method toggle() { this.open = ! this.open } yang ditambahkan
pada x-data. Method ini sekarang dapat dipanggil dari manapun di dalam
komponen.
32
}">
<button @click="toggle()">Toggle Content</button>
<div x-show="isOpen">
Content...
</div>
</div>
Pada kasus ini ini ada keuntungan tak terlihat. Pada beberapa
kasus, getter berguna untuk menyiasati akan syntax yang lebih ekspresif
di komponen anda.
Data-less components
Pada kasus ini ini anda dapat selalu mengoper sebuah objek kosong.
<div x-data="{}">
Meskipun, jika anda ingin, anda dapat menghapus nilai atribut seluruhnya
jika Itu tampak lebih bagus untuk anda.
<div x-data></div>
Single-element components
33
Re-useable data
Jika anda mendapati diri Anda menduplikasi konten dari x-data atau anda
mendapati suntax yang bertele-tele, Anda dapat mengekstrak x-data objek
ke sebuah komponen yang terdedikasi menggunakan Alpine.data
<div x-show="open">
Content...
</div>
</div>
<script>
document.addEventListener('alpine:init', () => {
Alpine.data('dropdown', () => ({
open: false,
toggle() {
this.open = ! this.open
},
}))
})
</script>
x-init
Direktif x-init yang memungkinkan anda untuk menghubungkan (hook) ke
fase inisialisasi dari elemen manapun di Alpine.
34
$nextTick
Standalone x-init
35
console.log(
'I will get evaluated when initializing each "dropdown" component.'
);
},
}));
x-show
x-show merupakan salah satu direktif yang berguna dan kuat di Alpine. x-
show menyediakan sebuah cara ekspresif untuk menampilkan dan
menyembunyikan DOM element
*jika “defaul” state sebuah x-show pada halaman muat berniali “false”,
anda mungkin ingin menggunakan x-cloak pada halaman untuk
menghindari “page flicker” (efek yang terjadi ketika peramban render
konten anda sebelum Alpine selesai inisialisasi dan menyembunyikannya)
With translation
Jika anda ingin menerapkan transisi yang halus ke perilaku x-show, anda
dapat menggunakan x-show dalam konjungsi dengan x-transition . ini
adalah sebuah contoh cepat dari komponen sama seperti diatas hanya
berbeda dengan diterapkannya transition.
<div x-data="{ open: false }">
<button x-on:click="open = ! open">Toggle Dropdown</button>
36
x-bind
x-bind memungkinkan anda untuk mengatur atribut HTML pada elemen
berdasarkan hasil dari ekspresi JavaScript.
Sebagai contoh, Ini adalah sebuah komponen yang akan kita gunakan x-
bind untuk mengatur placeholder nilai dari sebuah input.
Shorthand syntax
Ini adalah sebuah contoh dari dropdown tonggle sederhana, tapi alih-alih
menggunakan x-show kita akan menggunakan sebuah class “hidden” untuk
toggle elemennya.
<div x-data="{ open: false }">
<button x-on:click="open = ! open">Toggle Dropdown</button>
Shorthand Conditional
pada kasus seperti ini jika anda lebih suka syntax yang tidak bertele-tele
anda dapat menggunakan short-circuit evaluasinya JavaScript alih-alih
standar conditional:
<div :class="show ? '' : 'hidden'">
<!-- Is equivalent to: -->
37
<div :class="show || 'hidden'"></div>
Sebaliknya juga tersedia untuk anda, Bukannya menggunakan open kita
menggunakan sebuah variabel dengan nilai kebalikannya closed
<div :class="closed ? 'hidden' : ''">
<!-- Is equivalent to: -->
<div :class="closed && 'hidden'"></div>
Special behavior
Jika “class” ada atribut lainnya, :class akan menimpa atribut kelas yang
ada, karena opacity-50 akan ditimpa baik oleh hidden atau ''.
38
Meskipun Alpine memperlakukan class binding secara berbeda, Alpine
cukup pintar untuk mempertahankan kelas yang ada pada sebuah
elemen.
Sebagai contoh jika hide bernilai true, contoh diatas akan menghasilkan
DOM elemen seperti berikut:
<div class="opacity-50"></div>
perilaku ini ini sebaiknya tak terlihat dan dan intuitif untuk kebanyakan
pengguna tapi pantas untuk di disebut secara eksplisit untuk menjawab
pertanyaan developer atau kasus-kasus khusus yang mungkin muncul.
Binding Style
Mirip dengan syntax khusus untuk dinding kelas dengan objek JavaScript
Alpine juga menawarkan sebuah syntax berbasis objek untuk binding
atribut style
Seperti class objek, syntax ini sepenuhnya opsional. Hanya gunakan syntax
ini jika memberi keuntungan bagi anda.
39
salah satu keuntungan dari pendekatan ini adalah mampu untuk
mencampur dengan style yang sudah ada pada sebuah elemen:
Objek dapat berisi apapun yang yang normalnya ditulis sebagai sebuah
nama atribut di Alpine. Ini masuk directive Alpine dan modifier, tapi juga
HTML atribut biasa nilai objek bisa berupa string polos atau bisa juga
sebuah directif dinamis, atau callback yang dievaluasi oleh Alpine.
<div x-data="dropdown()">
<button x-bind="trigger">Open Dropdown</button>
<script>
document.addEventListener('alpine:init', () => {
Alpine.data('dropdown', () => ({
open: false,
trigger: {
['x-ref']: 'trigger',
['@click']() {
this.open = true
40
},
},
dialogue: {
['x-show']() {
return this.open
},
['@click.outside']() {
this.open = false
},
},
}))
})
</script>
x-on
x-on memungkinkan anda dengan mudah menjalankan kode pada
dispatch DOM event
* x-on hanya dapat mendengar sebuah event dengan nama lower case,
sebagai atribut HTML yang yang case-insensitive. Penulisan x-on:CLICK
akan mendengar (listen)pada sebuah event bernama click. Jika anda
butuh untuk mendengar ke sebuah event custom dengan nama
camelCase anda dapat menggunakan Helper .camel untuk bekerja di
sekitar batasan ini. Sebagai alternatif anda dapat menggunakan x-bind
untuk disisipkan pada direktif x-on sebuah elemen ke dalam kode
JavaScript (di mana kasus akan dipertahankan)
41
Shorthand Syntax
Jika Anda berharap mengakses objek event native JavaScript dari ekspresi
anda, anda dapat menggunakan properti magic $event milik Alpine.
<button @click="handleClick">...</button>
<script>
function handleClick(e) {
// Now you can access the event object (e) directly
}
</script>
keyboard event
Ini adalah sebuah contoh dari mendengarkan key Enter di dalam sebuah
input element
<input type="text" @keyup.enter="alert('Submitted!')">
Anda dapat juga merantai/menyambungkan (chain) modifier ini untuk
mencapai listener yang lebih kompleks.
Ini adalah sebuah listener yang berjalan ketika key Shift ditahan dan
Enter ditekan tapi tidak ketika Enter ditekan sendiri.
42
Anda dapat secara langsung menggunakan nama key apapun yang
valid melalui KeyboardEvent.key sebagai modifier dengan mengkonversinya
ke kebab-case.
<input type="text" @keyup.page-down="alert('Submitted!')">
untuk memudahkan referensi ini ada sebuah list key yang umum yang
mungkin anda ingin gunakan.
.shift Shift
.enter Enter
.space Space
.ctrl Ctrl
.cmd Cmd
.alt Alt
.escape Escape
.tab Tab
.equal Equal, =
.period Period, .
Custom Event
43
Ini adalah sebuah contoh komponen yang dispatch sebuah custom DOM
event dan listen juga.
<div x-data @foo="alert('Button Was Clicked!')">
<button @click="$event.target.dispatchEvent(new CustomEvent('foo', {
bubbles: true }))">...</button>
</div>
Ini adalah komponen yang sama yang ditulis ulang dengan properti
magic $dispatch.
<div x-data @foo="alert('Button Was Clicked!')">
<button @click="$dispatch('foo')">...</button>
</div>
Modifier
.prevent
.stop
Pada contoh diatas, mengklik tombol TIDAK AKAN menampilkan pesan. Ini
karena kita menghentikan propagation dari event segera dan tidak
44
mengizinkannya untuk “bubble” (menggembung) ke atas ke <div> dengan
listener @click padanya.
.outside
Ini karena .outside mendengarkan klik yang tidak berasal dari elemen
yang telah didaftarkan.
.window
.document
45
.document bekerja mirip dengan .window hanya .document mendaftarkan
listener pada standar pada document global dokumen, alih-alih pada
document global.
.once
.debounce
Sebagai contoh, jika anda memiliki sebuah kolom pencarian yang yang
memicu Network request ketika pengguna mengetik di kolom search
tersebut, penambahan sebuah dipotong akan mencegah Network
request dijalankan setiap kali penekanan tombol (keystroke).
<input @input.debounce="fetchResults">
Jika Anda berharap lebih panjang atau lebih pendek untuk waktu
“debounce”, Anda dapat melakukannya dengan menambahkan durasi
setelah modifier .debounce:
<input @input.debounce.500ms="fetchResults">
.throttle
46
Ini sangat berguna pada kasus dimana mungkin event dijalankan
berulang-ulang dan dan berkepanjangan dan penggunaan .debounce dan
tidak berfungsi karena anda masih ingin menghandle event yang sangat
sering.
Sebagai contoh:
<div @scroll.window.throttle="handleScroll">...</div>
Contoh di atas merupakan contoh yang bagus dari pelambatan
(throttling). Tanpa .throttle, method handleScroll dijalankan ratusan kali
ketika pengguna menggulir halaman kebawah. Ini dapat membuat
website menjadi lambat. Dengan menambahkan .throttle, kita
memastikan bahwa handleScroll hanya dapat dipanggil setiap 250
milidetik.
<div @scroll.window.throttle.750ms="handleScroll">...</div>
Sekarang, handleScroll hanya dipanggil setiap 750 milidetik.
.self
<button @click.self="handleClick">
Click Me
<img src="...">
</button>
Pada contoh diatas, kita memiliki sebuah tag <img> di dalam tag <button>.
Normalnya, klik apapun yang berasal dari elemen <button> (seperti pada
<img> contohnya), akan diambil oleh listener @click pada tombol.
.camel
<div @custom-event.camel="handleCustomEvent">
...
</div>
47
Terkadang Anda mungkin ingin untuk listen ke event camelCase seperti
customEvent pada contoh kita. Karena camelCase di dalam atribut html
tidak didukung, penambahan modifier .camel diperlukan untuk Alpine ke
nama event camelCase secara internal.
.dot
<div @custom-event.dot="handleCustomEvent">
...
</div>
Mirip dengan modifier .camelCase ada mungkin situasi dimana anda ingin
listen ke event yang yang memiliki titik dinamanya (sperti custom.event).
Karena dengan nama event dipakai oleh Alpine anda butuh menulis
dengan tanda hubung dan menambahkan modifier .dot
.passive
<div @touchstart.passive="...">...</div>
x-text
x-text mengatur konten teks dari sebuah elemen yang merupakan hasil
dari ekspresi.
48
<div x-data="{ username: 'calebporzio' }">
Username: <strong x-text="username"></strong>
</div>;
x-html
x-html mengatur property “innerHTML” dari sebuah elemen ke hasil yang
diberikan ekspresi.
x-model
<span x-text="message">
</div>
Sekarang, saat pengguna mengetik di dalam kolom teks, message akan
tercermini dalam <span>.
49
Anda dapat menggunakan contoh terompah di atas tapi kali ini, kita
menambah sebuah tombol untuk mengubah nilai dari property message.
<input type="text">
<textarea>
<input type="checkbox">
<input type="radio">
<select>
Text inputs
<span x-text="message"></span>
Textarea inputs
<textarea x-model="message"></textarea>
<span x-text="message"></span>
Checkbox Inputs
Radio Inputs
Select Inputs
single select
<select x-model="color">
<option>Red</option>
<option>Orange</option>
<option>Yellow</option>
</select>;
<select x-model="color">
<option value="" disabled>
Select A Color
</option>
<option>Red</option>
<option>Orange</option>
<option>Yellow</option>
</select>;
Multiple Select
51
Colors: <span x-text="color"></span>;
<select x-model="color">
<template x-for="color in ['Red', 'Orange', 'Yellow']">
<option x-text="color"></option>
</template>
</select>;
Modifier
.lazy
Pada text input, secara default, x-model update properti setiap kali
keystroke. Dengan penambahan modifier .lazy , anda dapat memaksa
sebuah input x-model untuk hanya update properti ketika fokus pergi dari
input element.
52
Ini berguna seperti ketika kolom pencarian real-time yang mengambil
data baru dari server setiap kali property search berubah.
.throttle
Interval default throttle adalah 250 milidetik, Anda dapat dengan mudah
mengubahnya dengan menambahkan sebuah modifier waktu.
Programmatic access
Anda dapat akses ini melalui sebuah properti bernama _x_model pada x-
model elemen. _x_model memiliki 2 method get dan set yang terikat dengan
property:
<button @click="$refs.div._x_model.set('phantomatrix')">
Change username to: 'phantomatrix'
</button>
<span x-text="$refs.div._x_model.get()"></span>
</div>
53
x-modelable
x-modelable memungkinkan anda untuk mengekspos properti Alpine
apapun sebagai target dari direktif x-model.
Seperti yang dapat Anda lihat properti dengan scope luar bernama
“number” sekarang terikat ke properti dalam bernama “count”.
x-for
Direktif x-for Alpine memungkinkan anda untuk membuat DOM element
dengan iterasi melalui sebuah list. Ini adalah contoh sederhana dari
penggunaan directive Alpine x-for untuk membuat sebuah list dari color
(warna) berdasarkan sebuah array.
54
<template> tersebut HARUS hanya memiliki satu root element
Keys
Keys penting untuk menentukan keys unik untuk setiap iterasi x-for jika
anda akan mengurutkan ulang item. Dengan key dinamis, Alpine mungkin
kesulitan melacak apa yang diurutkan ulang dan akan berdampak pada
ada efek samping yang aneh.
Sekarang jika color ditambahkan, dihapus, dan diurutkan ulang, atau “id”
mereka berubah, Alpine akan menjaga atau menghancurkan elemen <li>
yang sesuai.
Assessing indexes
Jika anda ada perlu akses indeks dari setiap item dalam iterasi, Anda
dapat melakukannya menggunakan sintaks ([item], [index]) in [items]:
Anda dapat juga mengakses index didalam sebuah ekspresi :key dinamis.
55
Iterating over a range
<ul>
<template x-for="i in 10">
<li x-text="i"></li>
</template>
</ul>;
x-transition
Alpine menyediakan sebuah utility transisi yang kokoh. Dengan beberapa
direktif x-transition, Anda dapat membuat transisi yang mulus ketika
sebuah elemen ditampilkan atau disembunyikan.
56
Anda dapat menimpa default ini dengan menambahkan modifier ke x-
transition .Ayo kita lihat modifier tersebut.
Customizing duration
Anda dapat melakukan konfigurasi durasi yang anda ingin untuk sebuah
tradisi dengan modifier .duration
<div> di atas akan bertransisi selama 500 milidetik ketika entering, dan 500
milidetik ketika leaving.
<div ...
x-transition:enter.duration.500ms
x-transition:leave.duration.400ms
>
Customizing Delay
Customizing opacity.
57
Customizing scale
<div ...
x-transition:enter.scale.80
x-transition:leave.scale.90
>
Seperti yang telah anda duga, nilai yang mungkin untuk penyesuaian ini
adalah top, bottom, left, dan right.
Untuk kendali langsung atas apa yang anda harapkan pada transisi, anda
dapat menerapakan class CSS pada setiap tahap transisi.
<div
x-show="open"
x-transition:enter="transition ease-out duration-300"
x-transition:enter-start="opacity-0 scale-90"
x-transition:enter-end="opacity-100 scale-100"
x-transition:leave="transition ease-in duration-300"
x-transition:leave-start="opacity-100 scale-100"
x-transition:leave-end="opacity-0 scale-90"
>Hello 👋</div>
</div>
Directive Description
x-effect
x-effect berguna untuk evaluasi ulang sebuah ekspresi ketika salah satu
dependensi berubah. Anda dapat berpikir ini adalah sebuah pengawas
(watcher) dimana anda tidak harus menentukan properti apa
yang perhatikan, direktif ini akan memperhatikan semua properti yang
digunakan dengannya.
59
Jika definisi ini membingungkan anda, tidak apa-apa. Lebih baik
dijelaskan melalui sebuah contoh:
<div x-data="{ label: 'Hello' }" x-effect="console.log(label)">
<button @click="label += ' World!'">Change Message</button>
</div>
ketika komponen ini dimuat, ekspresi x-effect akan berjalan dan “Hello
“akan di log ke console.
x-ignore
secara bawaan, Alpine mengikis atau menelusuri dan menginisialisasi
seluruh DOM tree dari sebuah elemen yang terdapat x-init atau x-data
Jika untuk beberapa alasan, anda tidak ingin bersentuhan dengan spesifik
bagian dari HTML anda, anda dapat mencegahnya dengan melakukan x-
ignore.
Pada contoh diatas tag <span> akan berisi “From Alpine” karena kita
memberitahu Alpine untuk mengabaikan konten dari div seluruhnya.
x-ref
x-ref dalam kombinasi dengan $refs merupakan sebuah utility yang
berguna untuk mengakses elemen DOM engan mudah secara
langsung. Ini sangat berguna sebagai sebuah pengganti elemen API
seperti getElementById dan querySelector.
60
x-cloak
Terkadang, ketika anda menggunakan AlpineJS untuk bagian dari
template anda, ada sebuah “blip” (kesalahan) ketika anda mungkin
melihat tempate tidak terinisialisasi setelah halaman dimuat, tapi
sebelum Alpine dimuat.
Jika anda ada ingin mencapai perilaku yang sama seperti ini, tapi
menghindari memasukkan global style, anda dapat menggunakan
trik keren berikut, tapi memang triknya aneh:
<template x-if="true">
<span x-text="message"></span>
</template>;
Ini akan menghasilkan gol yang sama seperti x-cloak hanya dengan
memanfaatkan cara kerja x-if
Lagi, solusi ini bukan untuk semua orang, tapi pantas untuk disebut untuk
kasus yang khusus.
61
x-teleport
directive x-teleport memungkinkan anda untuk mengangkut bagian dari
template Alpin Anda ke bagian DOM lain pada halaman sepenuhnya.
Direktif ini berguna untuk sesuatu seperti modal (khususnya yang yang
bersarang), dimana ini berguna untuk keluar dari set z-index dari
komponen Alpine saat ini.
**peringatan: jika anda adalah pengguna Livewire, fungsi ini tidak akan
bekerja di dalam komponen Livewire. Dukungan untuk ini masih di dalam
road map.
x-teleport
<body>
<div x-data="{ open: false }">
<button @click="open = ! open">Toggle Modal</button>
<template x-teleport="body">
<div x-show="open">
Modal contents...
</div>
</template>
</div>
...
</body>
62
perhatikan bagaimana ketika toggling modal, actual content model
ditampilkan SETELAH “Some other content...”? Ini karena ketika Alpine
menginisialisasi, Alpine melihat x-teleport="body" dan menambahkan dan
menginisialisasi elemen ke selector elemen yang disediakan.
Forwarding event
Untuk membuat pengalaman ini lebih mulus, Anda dapat “forward” event
dengan mendaftarkan event listener pada elemen <template x-teleport...>
seperti:
Perhatikan bahwa kita kini bisa mendengarkan event dispatch dari elemen
teleport dari luar elemen <template> itu sendiri?
63
Nesting
<template x-teleport="body">
<div x-show="open">
Modal contents...
<template x-teleport="body">
<div x-show="open">
Nested modal contents...
</div>
</template>
</div>
</div>
</template>
</div>
setelah toggling kedua modal “on”, modal sebagai children, tapi akan di
render sebagai sibling elemen pada halaman, tidak dalam satu sama
lainnya.
x-if
Karena ini merupakan perilaku yang berbeda, x-if tidak harus diterapkan
secara langsung ke element, tapi tag <template> yang membungkus
element. Cara ini, ini Alpine dapat menjaga catatan dari elemen sekali
saat dihapus dari halaman.
<template x-if="open">
<div>Contents...</div>
64
</template>;
x-id
x-id memungkinkan anda untuk mendeklarasikan “scope” baru untuk ID
baru manapun yang dihasilkan menggunakan $id(). x-id menerima
sebuah array string (ID name) dan menambahkan sebuah akhiran ke
setiap $id('...') yang dihasilkan yang unik daripada ID lain di halaman.
<div x-id="['text-input']">
<label :for="$id('text-input')">Username</label>
<!-- for="text-input-1" -->
<div x-id="['text-input']">
<label :for="$id('text-input')">Username</label>
<!-- for="text-input-2" -->
65
Magics
$el
$el merupakan sebuah properti magic yang dapat digunakan
untuk mengambil node DOM saat ini.
$refs
$refs merupakan sebuah properti magic yang dapat digunakan untuk
mengambil DOM elemen yang ditandai dengan x-ref di dalam komponen.
Ini berguna ketika anda memerlukan manipulasi DOM element secara
manual ini sering digunakan sebagai sebuah alternatif yang lebih pendek,
dari document.querySelector.
$store
anda dapat menggunakan $store dengan nyaman untuk mengakses
global Alpine store yang telah terdaftar menggunakan Alpine.store(…)
Sebagai contoh:
...
<script>
document.addEventListener('alpine:init', () => {
Alpine.store('darkMode', {
on: false,
toggle() {
this.on = ! this.on
}
})
66
})
</script>
Single-value Stores
jika anda ada tidak foto seluruh objek untuk sebuah store, anda dapat
mengatur dan menggunakan segala jenis data sebagai sebuah store.
Ini adalah contoh dari atas tapi menggunakan hal yang lebih sederhana
seperti sebuah nilai Boolean:
...
<script>
document.addEventListener('alpine:init', () => {
Alpine.store('darkMode', false)
})
</script>
$watch
Anda dapat “mengawasi” sebuah properti komponen menggunakan
magic method $watch . Sebagai contoh:
Pada contoh diatas, ketika tombol ditekan dan open berubah, callback
yang disediakan akan dipicu dan menambahkan nilai baru ke console.log.
67
Anda dapat mengawasi properti bersarang menggunakan notasi “dot”
ketika <button> ditekan, foo.bar akan set ke “bob”, dan “bob” akan di log ke
console.
ketika <button> ditekan, foo.bar akan set “bob”, dan "{bar: 'bob'} {bar: 'baz'}"
akan di log ke konsol(baru dan lama)
68
$dispatch
$dispatch merupakan sebuah jalan pintas yang berguna untuk dispatching
browser event.
<div @notify="alert($event.detail.message)">
<button @click="$dispatch('notify', { message: 'Hello World!' })">
Notify
</button>
</div>
Contoh:
Contoh:
<div
x-data="{ title: 'Hello' }"
@set-title.window="title = $event.detail"
>
<h1 x-text="title"></h1>
</div>
<div x-data>
<button @click="$dispatch('set-title', 'Hello World!')">Click me</button>
</div>
<!-- When clicked, the content of the h1 will set to "Hello World!". -->
Dispatching to x-model
$nextTick
$nextTick merupakan sebuah properti magic yang memungkinkan anda
untuk hanya mengeksekusi sebuah ekspresi SETELAH Alpine menerima
reaktif update DOM. Ini berguna setiap kali anda ingin berinteraksi dengan
DOM state SETELAH mencerminkan data apa pun yang anda buat.
70
<div x-data="{ title: 'Hello' }">
<button
@click="
title = 'Hello World!';
$nextTick(() => { console.log($el.innerText) });
"
x-text="title"
></button>
</div>
pada contoh diatas, daripada log “Hello” ke consol, “Hello World!” akan di
log karena $nextTick akan menunggu sampai Alpine selesai melakukan
update DOM.
Promises
$root
$root merupakan sebuah properti magic yang dapat digunakan untuk
mengambil root elemen dari komponen Alpine manapun. Dengan kata
lain elemen terdekat dari DOM tree yang berisi x-data.
71
$data
$data merupakan sebuah properti magic yang memberi Anda akses ke
lingkup data Alpine (saat ini umumnya disediakan oleh x-data).
Meskipun, terkadang ini berguna untuk memiliki sebuah objek aktual yang
terenkapsulasi semua scope yang dapat anda oper disekitar fungsi yang
lain.
<script>
function sayHello({ greeting, name }) {
alert(greeting + ' ' + name + '!')
}
</script>
kebanyakan aplikasi tidak membutuhkan properti magic ini, tapi ini dapat
sangat berguna untuk utilitas Alpine yang lebih kompleks dan lebih dalam.
$id
$id merupakan sebuah properti magic yang dapat digunakan untuk
menghasilkan ID elemen dan memastikan ID tidak akan bentrok dengan ID
lain dengan nama yang sama pada halaman yang sama.
72
Sesuatu seperti komponen input, modal, listboxes, dan lain-lain. akan
mendapat manfaat dari utility ini.
Basic Usage
Andai anda memiliki dua input element dihalaman dan anda ingin input
tersebut memiliki sebuah ID unik satu dengan yang lainnya Anda dapat
melakukan hal berikut:
seperti yang dapat anda lihat, $id mengambil sebuah string dan
memecahnya dan penambahan akhiran yang unik pada halaman.
Hal ini menyebabkan masalah, anda kini butuh untuk bisa mereferensi ke
ID yang sama dua kali. Satu untuk atribut for nya <label>, satu lagi untuk
id pada input.
Ini adalah cara yang mungkin Anda pikir dapat menyelesaikan masalah
ini dan sepenuhnya valid:
Pendekatan ini baik-baik saja, tetapi, memiliki name dan store di ID lingkup
komponen serasa rumit.
73
Untuk menyelesaikan tugas yang sama dengan cara yang lebih
fleksibel, anda dapat menggunakan directive x-id untuk dideklarasikan
sebuah “scope id” untuk serangkaian id:
<div x-id="['text-input']">
<label :for="$id('text-input')"> <!-- "text-input-1" -->
<input type="text" :id="$id('text-input')"> <!-- "text-input-1" -->
</div>
<div x-id="['text-input']">
<label :for="$id('text-input')"> <!-- "text-input-2" -->
<input type="text" :id="$id('text-input')"> <!-- "text-input-2" -->
</div>
Seperti yang dapat Anda lihat, x-id menerima sebuah array dari nama
ID. Sekarang penggunaan $id() dalam scope tersebut akan
menggunakan ID yang sama. Pikirkan mereka sebagai “grup id”.
Nesting
<div x-id="['text-input']">
<label :for="$id('text-input')"> <!-- "text-input-1" -->
<input type="text" :id="$id('text-input')"> <!-- "text-input-1" -->
<div x-id="['text-input']">
<label :for="$id('text-input')"> <!-- "text-input-2" -->
<input type="text" :id="$id('text-input')"> <!-- "text-input-2" -->
</div>
</div>
Untuk itu, $id() menerima sebuah parameter kedua opsional yang akan
menambahkan sebuah akhiran dari ID yang dihasilkan.
Contoh yang umum dari kebutuhan ini ialah terkadang seperti komponen
list box yang menggunakan atribut aria-activedescendant
untuk memberitahu teknologi bantu elemen mana yang “aktif” di list:
74
<ul
x-id="['list-item']"
:aria-activedescendant="$id('list-item', activeItem.id)"
>
<template x-for="item in items" :key="item.id">
<li :id="$id('list-item', item.id)">...</li>
</template>
</ul>
ini merupakan contoh dari sebuah listbox yang belum lengkap, tapi tetap
berguna untuk mendemonstrasikan sebuah skenario di mana anda
mungkin membutuhkan setiap ID di dalam sebuah grup untuk tetap unik
di tiap halaman, tapi juga ke dengan sebuah Loop yang dapat anda
referensi sebagai identifikasi dual dalam grup tersebut.
75
Globals
Alpine.data
Alpine.data(...) menyediakan sebuah cara untuk menggunakan ulang
konteks x-data dalam aplikasi anda.
<div x-data="dropdown">
<button @click="toggle">...</button>
<div x-show="open">...</div>
</div>
<script>
document.addEventListener('alpine:init', () => {
Alpine.data('dropdown', () => ({
open: false,
toggle() {
this.open = ! this.open
}
}))
})
</script>
Seperti yang dapat Anda lihat kita telah mengekstrak properti dan method
kita biasanya mendefinisikan secara langsung didalam x-data kedalam
sebuah objek komponen Alpine yang terpisah.
Alpine.data('dropdown', dropdown)
Alpine.start()
76
Ini menggunakan asumsi bahwa anda telah memiliki sebuah file yang
bernama dropdown.js dengan konten berikut:
toggle() {
this.open = !this.open;
},
});
Initial parameter
<div x-data="dropdown(true)">
Alpine.data('dropdown', (initialOpenState = false) => ({
open: initialOpenState
}))
Sekarang, anda dapat menggunakan ulang objek dropdown, tapi
menyediakannya dengan parameter yang yang berbeda ada Seperti
yang anda butuhkan.
Init functions
jika komponen anda berisi sebuah method init(), Alpine akan secara
otomatis mengeksekusinya sebelum fungsi itu merender
komponen. Sebagai contoh:
Alpine.data("dropdown", () => ({
init() {
// This code will be executed before Alpine
// initializes the rest of the component.
},
}));
77
Using Magic Properties
Jika anda ingin akses method magic atau properti dari sebuah objek
komponen, anda dapat melakukannya menggunakan context this:
Alpine.data('dropdown', () => ({
open: false,
init() {
this.$watch('open', () => {...})
}
}))
Jika Anda berharap untuk menggunakan ulang lebih dari pada hanya
data objek dari sebuah komponen, Anda dapat mengeksplorasi seluruh
template Alpine direktif menggunakan x-bind.
<div x-data="dropdown">
<button x-bind="trigger"></button>
<div x-bind="dialogue"></div>
</div>;
Alpine.data("dropdown", () => ({
open: false,
trigger: {
["@click"]() {
this.open = !this.open;
},
},
dialogue: {
["x-show"]() {
return this.open;
},
},
}));
78
Alpine.store
Alpine menawarkan global state management melalui API Alpine.store().
Registering A Store
<script>
document.addEventListener('alpine:init', () =>{" "}
{Alpine.store("darkMode", {
on: false,
toggle() {
this.on = !this.on;
},
})}
)
</script>;
Dari bundle:
Alpine.store("darkMode", {
on: false,
toggle() {
this.on = !this.on;
},
});
Alpine.start();
Accessing store
Anda dapat mengakses data dari Store manapun di dalam ekspresi Alpine
menggunakan magic properti $store:
79
<div x-data:class="$store.darkMode.on && 'bg-black'">...</div>;
Anda dapat juga memodifikasi properti di dalam struktur dan semua yang
bergantung pada properti tersebut akan secara otomatis bereaksi.
Sebagai contoh:
<script>Alpine.store('darkMode').toggle()</script>;
Initializing stores
<script>
document.addEventListener('alpine:init', () =>{" "}
{Alpine.store("darkMode", {
init() {
this.on = window.matchMedia("(prefers-color-scheme: dark)").matches;
},
on: false,
toggle() {
this.on = !this.on;
},
})}
)
</script>;
80
warna milik browser (peramban) sebelum Alpine merender apapun di
halaman.
Single-value Store
anda tidak butuh keseluruhan objek untuk sebuah Store, Anda dapat
mengatur dan menggunakan data jenis apapun sebagai Store.
Ini adalah sebuah contoh dari di atas tapi menggunakan ini yang lebih
sederhana seperti nilai boolean:
...
<script>
document.addEventListener('alpine:init', () => {
Alpine.store('darkMode', false)
})
</script>
Alpine.bind
Alpine.bind(...) menyediakan cara untuk menggunakan ulang objek x-
bind di dalam aplikasi anda.
<button x-bind="SomeButton"></button>
<script>
document.addEventListener('alpine:init', () => {
81
Alpine.bind('SomeButton', () => ({
type: 'button',
'@click'() {
this.doSomething()
},
':disabled'() {
return this.shouldDisable
},
}))
})
</script>
82
Plugin
Mask Plugin
Mask pluginnya Alpine memungkinkan anda untuk memformat secara
otomatis sebuah kolom input text saat user mengetik.
Ini berguna pada tipe input yang berbeda: nomor telepon, kartu
kredit, jumlah dolar, nomor akun, tanggal l, dan lain-lain.
Installation
anda dapat menggunakan plugin ini dengan cara menginstalnya via NPM
atau menyatakannya dengan tag <script>
Via CDN
Via NPM
Anda dapat menginstal Mask dari NPM untuk digunakan dalam bundel
(bundle):
Alpine.plugin(mask)
...
x-mask
83
Ayo mulai dengan melihat contoh sederhana dari sebuah input data
tanggal:
* karakter apapun
Dynamic Masks
Ini adalah sebuah contoh dari input kartu kredit yang butuh untuk dirubah
berdasarkan mask jika nomor dimulai dengan nomor “34” atau “37” (yang
berarti ini adalah sebuah kartu American Express dan memiliki format
yang berbeda).
<input x-mask:dynamic="
$input.startsWith('34') || $input.startsWith('37')
? '9999 999999 99999' : '9999 9999 9999 9999'
"></input>
seperti yang dapat Anda lihat di contoh diatas. Setiap kali pengguna
mengetik di dalam kolom input, nilai tersebut akan di oper ke ekspresi
sebagai $input. Berdasarkan $input, mask yang berbeda dimanfaatkan di
dalam kolom.
84
Coba sendiri dengan mengetikkan sebuah nomor yang di mulai dengan
“34” dan yang satu tidak.
<input x-mask:dynamic="creditCardMask">
<script>
function creditCardMask(input) {
return input.startsWith('34') || input.startsWith('37')
? '9999 999999 99999'
: '9999 9999 9999 9999'
}
</script>
Money Inputs
Karena menulis ekspresi mask dinamis anda sendiri untuk input uang
sangatlah kompleks, Alpine menawarkan fungsi tersebut yang telah
dibuat sebelumnya dan tersedia dengan $money()
<input x-mask:dynamic="$money($input)">
jika ingin menukar dengan titik “.” dengan koma “,” atau sebaliknya(seperti
persyaratan pada mata uang tertentu) Anda dapat melakukannya
menggunakan parameter opsional kedua:
Intersect Plugin
Intersect plugin merupakan pembungkus untuk intersection observer yang
memungkinkan anda untuk bereaksi dengan mudah ketika sebuah
elemen masuk ke viewport.
Ini berguna untuk: lazy loading gambar dan konten lain, memicu
animasi, scroll tanpa batas, logging “view” dari content, dan lain-lain.
Installation
85
Via CDN
Anda dapat memasukkan CDN yang build dari plugin ini sebagai sebuah
tag <script>, pastikan untuk menyertakan SEBELUM file inti dari Alpine CS.
Anda dapat menginstal intersect dari NPM untuk digunakan dalam bundel
anda:
Alpine.plugin(intersect)
...
x-intersect
API utama untuk menggunakan plugin ini adalah x-intersect. Anda dapat
menambahkan x-intersect ke elemen manapun di dalam komponen
Alpine, dan ketika komponen tersebut memasuki area pandang (di scroll
ke area pandang), ekspresi yang disediakan akan dieksekusi.
Sebagai contoh, pada potongan kode berikut, shown tetap bernilai false
sampai elemen di scroll ke bawah. Pada titik ini, ekspresi mengeksekusi
dan shown menjadi true:
x-intersection:enter
86
Akhiran :enter merupakan sebuah alias dari x-intersect, dan berfungsi
dengan cara yang sama.
x-intersect:leave
Modifiers
. once
.half
. full
87
<div x-intersect.full="shown = true">...</div> // when `0.99` of the element
is in the viewport
.threshold
Nilai ini harus berada di jangkauan “0-100”. Nilai “0” berarti memicu
sebuah “intersection” jika bagian elemen MANA PUN memasuki
viewport(perilaku bawaan). Ketika sebuah nilai “100” berarti jangan picu
intersection sampai seluruh halaman telah enter sebelumnya.
Jika anda ingin memicu hanya 5% dari elemen yang memasuki viewport
anda dapat menggunakan .threshold.05 dan seterusnya dan seterusnya.
.margin
88
<div x-intersect:leave.margin.10%.25px.25.25px="loaded = false">...</div> //
Unload when the element gets within 10% of the top of the viewport, or within
25px of the other three edges
Persist Plugin
Persist plugin memungkinkan anda untuk mempertahankan state Alpine di
semua halaman.
Ini berguna untuk mempertahankan filter pencari, active tab dan fitur lain
dimana pengguna akan frustasi jika konfigurasi mereka di-reset setelah
merefresh atau meninggalkan dan mengunjungi ulang halaman.
Installation
Via CDN
Anda dapat memasukkan CDN build pada plugin ini sebagai sebuah tag
<script>, pastikan masukkannya SEBELUM file inti Alpine JS.
Anda dapat menginstal Persist dari NPM untuk digunakan dalam bundel
anda:
Alpine.plugin(persist)
...
89
$persist
API utama untuk menggunakan plugin ini adalah method magic $persist
<span x-text="count"></span>
</div>;
Jika sebuah nilai dibungkus dalam $persist, ada inisialisasi Alpine akan
mendaftarkan wwatcher sendiri untuk nilai tersebut. Sekarang setiap kali
nilai berubah untuk alasan apapun Alpine akan menyimpan nilai baru ke
dalam localstorage.
90
Anda akan mendapat mengamati bahwa dengan mengunjungi halaman
ini, Alpine telah mengatur nilai “count” didalam localstorage. Ada juga
menyadari imbuhan nama property “count” dengan “x” sebagai cara
nama spasi dari nilai ini jadi Alpine tidak bentrok dengan tool lain yang
menggunakan localStorage.
Sekarang ubah “count” sesuai contoh berikut dan amati perubahan yang
Alpine buat ke localstorage.
<span x-text="count"></span>
</div>;
$persist bekerja dengan nilai primitif seperti array dan objek. Meskipun
perlu diperhatikan bahwa localstorage harus dihapus ketika tipe variabel
berubah. Mengingat contoh sebelumnya, jika kita mengubah nilai dari
$persist({ value: 0 }) , kemudian localstorage akan menghapus atau
memberi nama ulang ke variabel “count”.
Pada kasus ini, anda dapat mengatur custom key ke anda sendiri untuk
mempertahankan nilai apapun menggunakan modifier .as:
91
<div x-data="{ count: $persist(0).as('other-count') }">
<button x-on:click="count++">Increment</button>
<span x-text="count"></span>
</div>;
Ini adalah tampilan Chrome Dev tool untuk Anda lihat sendiri.
Perhatikan skenario di mana anda ingin menghapus data setiap kali user
menutup tab. Pada kasus ini anda dapat mempertahankan data ke
sessionStorage menggunakan modifier .using:
<span x-text="count"></span>
</div>;
<script>
92
window.cookieStorage = {
getItem(key) {
let cookies = document.cookie.split(";");
for (let i = 0; i < cookies.length; i++) {
let cookie = cookies[i].split("=");
if (key == cookie[0].trim()) {
return decodeURIComponent(cookie[1]);
}
}
return null;
},
setItem(key, value) {
document.cookie = key+' = '+encodeURIComponent(value)
}
}
</script>
<span x-text="count"></span>
</div>;
Alpine.data("dropdown", function () {
return {
open: this.$persist(false),
};
});
Alpine.store("darkMode", {
on: Alpine.$persist(true).as("darkMode_on"),
});
93
Focus Plugin
*perhatikan: Plugin ini sebelumnya bernama “Trap”. fungsi Trap telah di
serap ke dalam plugin ini dengan tambahan fungsi. Anda dapat
menggeser ke fokus tanpa apa perubahan dan yang rusak.
Installation
Via CDN
Anda dapat memasukkan CDN build pada plugin ini sebagai sebuah tag
<script>, pastikan masukkannya SEBELUM file inti Alpine JS.
Via NPM
Anda dapat menginstal Focus dari NPM untuk digunakan didalam bundel
anda.
Alpine.plugin(focus)
...
94
x-trap
Sebagai contoh:
Nesting dialogs
Terkadang Anda ingin mencari satu dialog di dalam dialog lainnya. x-trap
membuatnya mudah untuk menanganinya secara otomatis.
Mekanisme ini rekursif, Jadi anda dapat menangkap fokus yang telah
tertangkap di elemen tanpa batas kemudian “melepasnya” setiap elemen
secara secara berurutan.
95
...
...
Modifier
.inert
<div>
...
</div>
</body>
96
<div aria-hidden="true">
...
</div>
</body>
.noscroll
Sebagai contoh:
.noreturn
Sebagai contoh:
97
div x-data="{ open: false }" x-trap.noreturn="open">
<input type="search" placeholder="search for something" />
<div x-show="open">
Search results
$fokus
Plugin ini menawarkan banyak utility kecil untuk mengatur fokus di dalam
halaman. Utilitas ini diekspos melalui magic $focus
Property Deskripsi
98
ketika mengambil “selanjutnya” atau “sebelumnya”
menggunakan “web round” (kecuali mengembalikan
wrap()
elemen pertama jika terdapat elemen “selanjutnya” pada
elemen terakhir
Ayo lanjut dengan beberapa contoh dari penggunaan utility ini. Contoh di
bawah memungkinkan pengguna untuk mengendalikan fokus di dalam
kelompok tombol menggunakan arraw key (tombol panah). Anda dapat
mengujinya dengan klik pada tombol kemudian menggunakan tombol
panah untuk memindah fokus di sekitar.
<div
@keydown.right="$focus.next()"
@keydown.left="$focus.previous()"
>
<button>First</button>
<button>Second</button>
<button>Third</button>
</div>
Perhatikan jika tombol terakhir yang difokus, tekan “panah kanan” tidak
akan melakukan apapun. Ayo tambahkan method .wrap() sehingga fokus
membungkus semuanya.
<div
@keydown.right="$focus.wrap().next()"
@keydown.left="$focus.wrap().previous()"
>
<button>First</button>
<button>Second</button>
<button>Third</button>
</div>
99
Sekarang, ayo tambahkan 2 tombol, 1 fokus ke elemen pertama dari
kelompok tombol dan fokus lain ke elemen terakhir:
<div
x-ref="buttons"
@keydown.right="$focus.wrap().next()"
@keydown.left="$focus.wrap().previous()"
>
<button>First</button>
<button>Second</button>
<button>Third</button>
</div
Collapse Plugin
Collapse pada Alpine memungkinkan anda mengembangkan dan
meruntuhkan elemen menggunakan transisi yang mulus.
Karena perilaku dan implementasi ini berbeda dari standar sistem transisi
Alpine, fungsionalitas ini telah dibuat ke dalam plugin yang
terdedikasi/dikhususkan.
Installation
Anda dapat menggunakan plugin ini baik dari tag <script> atau
menginstalnya melalui NPM:
Via CDN
Anda dapat memasukkan CDN build dari plugin ini sebagai tag
<script>, pastikan untuk memasukkannya sebelum file inti Alpine JS.
100
Via NPM
Anda dapat install Collapse dari NPM untuk digunakan bundel anda:
Alpine.plugin(collapse)
...
x-collapse
x-collapse hanya ada pada sebuah elemen yang telah memiliki directive
x-show. Ketika ditambahkan sebuah elemen x-show, x-collapse akan secara
mulus “mengembang” dan “meruntuhkan” elemen ketika visibilitasnya di
toggle melalui animasi properti height.
Sebagai contoh:
Modifier
.duration
101
<p x-show="expanded" x-collapse.duration.1000ms>
...
</p>
</div>
.min
Secara bawaan, state “collapsed” mengatur tinggi dari elemen ke 0px dan
juga mengatur display: none;
Morph Plugin
Plugin Morph memungkinkan anda untuk “mengubah” elemen pada
halaman menjadi template html yang telah disediakan, sambil
mempertahankan peramban (browser) atau state Alpine apapun di
dalam elemen yang “diubah”.
Ini berguna untuk memperbarui HTML dari sebuah request peladen tanpa
kehilangan state pada halaman Alpine. Utility seperti inti adalah ini dari
Framework s full-stack seperti Laravel Livewire dan Phoenix Live View.
102
Installation
Via CDN
Anda dapat memmasukkan CDN build plugin ini sebagai sebuah tag
<script>, pastikan memasukkannya sebelum file inti Alpine JS.
Via NPM
Anda dapat menginstal Morph dari NPM untuk digunakan di bundel anda
103
import Alpine from 'alpinejs'
import morph from '@alpinejs/morph'
window.Alpine = Alpine
Alpine.plugin(morph)
...
Alpine.morph()
Parameter Deskripsi
<div x-data="{ message: 'Change me, then press the button!' }">
<input type="text" x-model="message">
<span x-text="message"></span>
</div>
<button>Run Morph</button>
<script>
document.querySelector('button').addEventListener('click', () => {
let el = document.querySelector('div')
Alpine.morph(el, `
<div x-data="{ message: 'Change me, then press the button!' }">
104
<h2>See how new elements have been added</h2>
Lifecycle Hooks
ini adalah selalu aktual, saat ini, dan elemen pada halaman
el
akan “ditambal“ (diubah oleh Morph)
105
Sebuah fungsi yang dapat ketika dipanggil dalam “hook”
skip() akan melewati pembandingan atau penambalannya sendiri
dan children dari Element saat ini.
Option Deskripsi
106
.
Ini adalah kode dari semua lifecycle untuk referensi yang lebih konkrit:
Alpine.morph(el, newHtml, {
updating(el, toEl, childrenOnly, skip) {
//
},
updated(el, toEl) {
//
},
removing(el, skip) {
//
},
removed(el) {
//
},
adding(el, skip) {
//
},
added(el) {
//
},
key(el) {
// By default Alpine uses the `key=""` HTML attribute.
return el.id;
},
Keys
107
Karena batasan ini, Morph memiliki sebuah sistem “key” yang
memungkinkan developer untuk memaksa elemen tertentu ditahan
daripada menggantinya.
Penggunaan umum kasus ini Ini adalah sebuah daftar sibling di dalam
sebuah pengulangan. Dibawah ini adalah contoh alasan key terkadang
dibutuhkan.
Mengingat situasi di atas, Morph tidak memiliki cara untuk tahu bahwa
node “Travis” telah dihapus dari DOM tree. Pikirkan bahwa “Mark” telah
berubah ke “Travis” dan “Travis” berubah ke “Tom”.
Ini bukan yang sebenarnya kita inginkan, kita ingin untuk menyimpan
elemen original alih-alih mengubahnya, MEMINDAHKAN mereka ke dalam
<ul>.
108
Sekarang terdapat “keys” di <li>, Morph mencocokkan mereka ke-2 DOM
tree dan memindah mereka.
109
Advanced
Reactivity
Alpine merupakan “reaktif” dalam arti ketika anda mengubah bagian dari
data, semua yang bergantung pada data tersebut secara otomatis
bereaksi pada perubahan tersebut.
Setiap reaktivitas kecil yang yang terjadi di Alpine, terjadi karena 2 fungsi
reaktif penting di inti Alpine: Alpine.reactive() dan Alpine.effect()
Alpine.reactive()
Mari kita lihat pada Alpine.reactive(). Fungsi ini menerima sebuah object
JavaScript sebagai parameter dan mengembalikan sebuah versi “reaktif”
dari objek tersebut. Sebagai contoh:
onsole.log(data.count); // 1
console.log(reactiveData.count); // 1
reactiveData.count = 2;
console.log(data.count); // 2
console.log(reactiveData.count); // 2
110
Apa yang Anda lihat disini ini terjadi karena reactiveData ialah pembungkus
kecil disekitar data, setiap upaya untuk get atau set sebuah properti akan
berperilaku tepat seperti ini seperti jika anda berinteraksi dengan data
secara langsung.
Alpine.effect()
Alpine.effect(() => {
console.log(data.count);
});
Ketika kode ini dijalankan, “1” akan di log ke console. Kapanpun data.count
berubah nilai akan di log ke console lagi.
<button>Increment</button>;
111
Count: <span></span>;
Alpine.effect(() => {
span.textContent = data.count;
});
button.addEventListener("click", () => {
data.count = data.count + 1;
});
Seperti yang dapat Anda lihat, anda dapat membuat data reaktif
apapun. Dan dapat juga dapat membungkus kedalam fungsionalitas
manapun didalam Alpine.effect
Extending
Alpine memiliki basis code yang dibuka yang memungkinkan ekstensi
dalam beberapa cara. Faktanya, setiap directive dan magic yang
tersedia di Alpine sendiri menggunakan API yang tepat. Dalam teori anda
dapat membangun ulang semua fungsionalitas Alpine dan
menggunakannya untuk anda sendiri.
Lifecycle concerns
Sebelum kita mendalami setiap individual API, pertama mari kita bahas
tentang lokasi basis kode anda harus API.
112
Ada dua teknik berbeda bergantung pada ada jika anda mengimpor
Alpine kedalam bundel atau masukkannya melalui tag <script>. Mari lihat
keduanya:
Ini contohnya:
<html>
<script src="/js/alpine.js" defer></script>
<script>
document.addEventListener('alpine:init', () => {
Alpine.directive('foo', ...)
})
</script>
</html>
Jika anda ingin mengekstrak ekstensi kode anda sendiri kedalam sebuah
file eksternal, anda perlu memastikan bahwa file tag <script> tersebut
berlokasi SEBELUM file Alpine.
<html>
<script src="/js/foo.js" defer></script>
<script src="/js/alpine.js" defer></script>
113
Alpine.directive('foo', ...)
window.Alpine = Alpine
window.Alpine.start()
Sekarang kita tahu dimana menggunakan API extension ini, mari lihat
lebih dekat bagaimana penggunaan masing-masing:
Custom Directive
Method Signature
Alpine.directive(
"[name]",
(el, { value, modifiers, expression }, { Alpine, effect, cleanup }) => {});
expression Bagian nilai atribut dari directive. Contoh: law dari x-foo=”law”
114
Simple Example
Alpine.directive('uppercase', el => {
el.textContent = el.textContent.toUpperCase()
})
<div x-data>
<span x-uppercase>Hello World!</span>
</div>
Evaluating expressions
Seperti berikut:
console.log(evaluate(expression));
});
115
Introduksi reactivity
effect(() => {
getThingToLog((thingToLog) => {
console.log(thingToLog);
});
});
});
Anda mungkin menyadari fungsi ini dari x-effect. Ini memiliki mekanisme
yang sama di belakang layar.
getThingToLog((thingToLog) => {
console.log(thingToLog);
});
Sekarang kita dapat memanggil getThingToLo yang jika anda panggil ulang
merupakan fungsi JavaScript versi aktual dari ekspresi string: “message”.
Alasan dari ini adalah untuk mendukung ekspresi asinkronus seperti await
getMessage(). Dengan mengoper sebuah callback “receiver”. Alih-alih
mendapatkan hasil secara langsung, anda ada diperbolehkan
menggunakan direktif untuk bekerja dengan ekspresi asinkronus.
Cleaning Up
117
Katakanlah anda butuh untuk mendaftarkan sebuah event listener dari
sebuah custom directive. Setelah direktif dihapus dari halaman untuk
alasan apapun, anda mungkin ingin menghapus event listener juga.
window.addEventListener("click", handler);
cleanup(() => {
window.removeEventListener("click", handler);
});
});
Sekarang jika direktif dihapus dari elemen ini atau elemennya sendiri
dihapus, event listener akan dihapus juga.
Custom magics
Method signature
118
Magic Property
Ini adalah sebuah contoh dari magic helper “$now” yang memudahkan
untuk mendapat waktu saat ini di mana pun di Alpine:
Alpine.magic("now", () => {
return new Date().toLocaleTimeString();
});
<span x-text="$now"></span>;
Sekarang tag <span> akan berisi waktu saat ini, menyerupai sesuatu seperti
“12:00:00 PM”.
Magic functions
Sebagai contoh, Jika anda ingin membuat fungsi magic $clipboard() yang
menerima sebuah string untuk meng-copy ke Clipboard, kita akan
mengimplementasikannya seperti ini:
Alpine.magic("clipboard", () => {
return (subject) => navigator.clipboard.writeText(subject);
});
119
Alpine.magic("clipboard", () => (subject) => {
navigator.clipboard.writeText(subject);
});
Kita akan memulai membuat ini untuk konsumsi tag <script> sederhana di
Alpine. Lalu meningkatkannya ke sebuah modul untuk diimpor ke dalam
bundel:
Script include
Mari kita mulai secara terbalik dengan melihat bagaimana plugin kita
akan dimasukkan ke dalam sebuah project.
<html>
<script src="/js/foo.js" defer></script>
<script src="/js/alpine.js" defer></script>
document.addEventListener('alpine:init', () => {
window.Alpine.directive('foo', ...)
120
window.Alpine.magic('foo', ...)
})
itu saja! membuat plugin untuk dimasukkan via tag script sangat
sederhana dengan Alpine.
Bundle module
window.Alpine = Alpine;
window.Alpine.start();
anda akan menyadari bahwa ada API baru di sini: Alpine.plugin(). Ini
adalah method Alpine yang berguna untuk expose dan mencegah
konsumen dari plugin anda dari harus mendaftar beberapa direktif dan
magic berbeda sendiri.
Sekarang lihat sumber dari plugin yang akan kita eksport dari foo
Async
Alpine dibangun untuk mendukung fungsi asinkronus di banyak tempat ini
mendukung yang standar.
<span x-text="getLabel()"></span>;
karena getLabel sinkronus, semua berfungsi seperti yang diperkirakan.
Selain itu, jika anda lebih suka memanggil method di dalam Alpine tanpa
diikuti tanda kurung, Anda dapat membiarkannya tanpa tanda kurung
dan Alpine akan mendeteksi fungsi yang disediakan sebagai fungsi
asinkronus dan menanganinya. Sebagai contoh:
<span x-text="getLabel"></span>;
Installation
122
Seperti semua ekstensi Alpine, anda dapat memasukkan melalui tag
<script> atau module import:
Script tag
<html>
<script src="alpinejs/alpinejs-csp/cdn.js" defer></script>
</html>;
Module import
window.Alpine = Alpine;
window.Alpine.start();
Restrictions
Sebagai contoh, sebuah komponen inline seperti ini tidak akan berfungsi.
<span x-text="count"></span>
</div>
Meskipun, memecah ekspresi ke dalam API eksternal, contoh berikut valid
dengan CSP build:
<span x-text="count"></span>
</div>
Alpine.data("counter", () => ({
123
count: 1,
increment() {
this.count++;
},
}));
*SELESAI*
124