We’ve seen how to define data using x-data
:
<div x-data="{ showThis: false }">
<p x-show="showThis">Show this</p>
</div>
The string passed to x-data
contains a JavaScript object, and we can add more variables into it:
<div x-data="{ showThis: false, name: '' }">
<p x-show="showThis">Show this</p>
</div>
But it’s kind of difficult to write JavaScript in this way, especially because it’s not syntax highlighted and being inside a string it’s easy to do errors and the editor cannot detect them for us.
You can do this instead:
Alpine.data('mydata', () => ({
showThis: false,
name: ''
}))
and then you associate mydata
to an HTML tag:
<div x-data="mydata">
</div>
and in its children (and on the element itself, if you need) you have access to the variables defined in mydata
:
<div x-data="mydata">
<p x-show="showThis">Show this</p>
</div>
This is very useful if you need to add methods that you can call when an event occurs, or when you have more complex data processing.
Simple example, I have a shopping cart and in addition to the data, I have some utility functions to format this data nicely in my UI:
Alpine.data('shop', () => ({
showCartOverlay: false,
cart: JSON.parse(localStorage.getItem('cart')) || [],
subtotal: 0,
subtotalFormatted() {
return this.formatAsPrice(this.subtotal)
},
formatAsPrice(price) {
return Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(price)
},
recalculateSubtotal() {
this.subtotal = 0
this.cart.map((item) => (this.subtotal = (parseInt(this.subtotal * 100) + parseInt(item.price * 100)) / 100))
}
})
.. you got the idea.
Now I can use functions like this:
<div x-data="shop">
...
<p class='ml-4' x-text='formatAsPrice(item.price)'></p>
</div>
It’s much cleaner than adding all those functions inside x-data
.
Lessons in this unit:
0: | Introduction |
1: | Installing Alpine |
2: | The basics of Alpine |
3: | Events |
4: | ▶︎ Defining data |
5: | Looping |
6: | Binding user input to variables |
7: | Watching variables change |
8: | Stores |