$el, $event and $nextTick
Magic properties are variables starting with $ that Alpine provides to every expression. You have already met $refs. Here are the three most useful ones: the element, the event, and waiting for the page to update.
$el
$el is the element the directive is on:
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
<div x-data>
<button @click="$el.textContent = 'Done'">Mark</button>
</div>After a click the button label changes to "Done". In real code, keep the text in data and output it with x-text, and use $el for things like focus or element sizes.
$event
$event is the event object — the same one a function passed to addEventListener receives. It holds the typed value, the pressed key, coordinates:
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
<div x-data>
<input @keydown="console.log($event.key)" placeholder="Press some keys">
</div>Every pressed key is printed in the console under the example: a, Enter, Backspace.
If the handler is a method name without parentheses, Alpine passes the event as the first argument:
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
<div x-data="{
search: '',
update(event) {
this.search = event.target.value;
}
}">
<input @input="update" placeholder="Search tasks">
<p x-text="'Searching for: ' + search"></p>
</div>@input="update" is the same as @input="update($event)".
$nextTick
Alpine does not update the page instantly but right after the current code finishes. $nextTick delays a function until the update has happened:
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
<div x-data="{ tasks: ['Buy milk'] }">
<button @click="
tasks.push('Call Oleg');
console.log('Right away:', $refs.list.children.length);
$nextTick(() => console.log('After the update:', $refs.list.children.length));
">Add</button>
<ul x-ref="list">
<template x-for="task in tasks">
<li x-text="task"></li>
</template>
</ul>
</div>After the first click the console shows "Right away: 2" and "After the update: 3". The list has one more child than there are tasks because the <template> itself sits in it. The point is that the new <li> exists only by the time of $nextTick.
Other magic properties
| Property | What it is |
|---|---|
$root | The component's root element, the one with x-data |
$data | The component's data object |
$dispatch | Sends a custom event |
$watch | Watches a property |
$store | Global store |
$dispatch and $watch are the next lesson, $store comes in the lesson on global state.
Common mistake
Expecting this.$el inside a method to be the button that was clicked. In methods from x-data, this.$el points to the component's root element, the one with x-data. To get the button, pass it explicitly — @click="mark($el)" — or take $event.target from the event.