It's no secret — I'm a huge fan of Alpine. For me, it hits that goldilocks zone between minimalistic and powerful. Alpine is straightforward to get started with, especially if you have a VueJS background. However, there are a few hidden features (okay, they're documented, not actually hidden) that you may not notice if you're just quickly scanning the readme.
Easy Show / Hide Transitions
Alpine includes support for custom transition classes via x-transition
, but did you know there's also an easier way to add show/hide transitions to your components? The x-show
directive also has an optional modifier transition
. Check it out:
<!-- no transition -->
<div x-show="open">I will appear abruptly with no transition.</div>
<!-- easy fade + scale -->
<div x-show.transition="open">I come and go with a nice transition.</div>
Beats having six lines of x-transition
class mappings for 80% of cases. However, it doesn't stop there! The transition modifier on x-show
also has other optional modifiers.
<!-- Modify the transition -->
<div x-show.transition.in="open">Only transition in.</div>
<div x-show.transition.out="open">Only transition out.</div>
<div x-show.transition.opacity="open">Only fade (no scaling).</div>
<div x-show.transition.scale="open">Only scaling (no fade).</div>
<div x-show.transition.duration.2000ms="open">Transition in for two seconds. Out for half of that.</div>
<div x-show.transition.origin.top.left="open">Transition starts and ends from the top left</div>
<!-- Combine modifiers. Go crazy! -->
<div x-show.transition.in.origin.top.left.opacity="open">
Only transition in from the top left with a fade.
</div>
For more examples, check out the full documentation of x-show
.
Camel Modifiers
Both x-bind
and x-on
support a .camel
modifier. I find the latter one is more useful (especially when working with Livewire), but they're both good to know about.
x-bind
<div x-bind:attribute-name.camel="someVar">...</div>
<!-- Result -->
<div attributeName="(value of someVar)">...</div>
x-on
<div x-on:your-event.camel="doSomething">
<!-- Result -->
<div @yourEvent="doSomething">
Model Modifiers
There are two modifiers you can use with x-model
— debounce
and number
. Both can be useful in the right situations. I didn't know that number
existed before writing this article!
Debounce
Delay updating the binding until a certain amount of time has passed since inputting something. In other words, when you stop typing it waits a little bit before updating the data. By default the time is 250ms
, but you can customize the debounce time if you wish.
<input x-model.debounce="name"> <!-- 250ms default -->
<input x-model.debounce.500="name"> <!-- 500ms -->
<input x-model.debounce.500ms="name"> <!-- 500ms -->
Number
This modifier tries to cast the value to a number instead of the string representation of that number. If it can't cast it easily to a number, the original value is returned unmodified.
<input x-model.number="age">
The x-spread
Operator
When you start to create more complex components, separating the logic and the template is a great pattern. If you come from a Vue background, you'll know this as single file components (.vue files). Separating template and logic is a great step, but the x-spread
object lets you take it even further by encapsulating the attribute bindings too! Take this component example:
<div x-data="dropdown()">
<button @click="show">Open</button>
<div x-show="open" @click.away="hide">
Dropdown contents
</div>
</div>
<script>
function dropdown() {
return {
open: false,
show() { this.open = true },
hide() { this.open = false },
}
}
</script>
Here's how it might look if we used x-spread
.
<div x-data="dropdown()">
<button x-spread="trigger">Open</button>
<div x-spread="contents">
Dropdown contents
</div>
</div>
<script>
function dropdown() {
return {
open: false,
trigger: {
['@click']() { this.open = true }
}
contents: {
['x-show']() { return this.open },
['@click.away']() {
this.open = false
},
}
}
}
</script>
I tried to keep the example small for this article, but you can imagine how useful this might be when you have many attributes on a component. You no longer have to cross-reference the HTML and the Javascript sections of components to figure out what's happening. Instead, x-spread
allows you to put everything in one spot.
Thanks for reading!