Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

x-data and component state

The x-data directive turns a regular element into an Alpine component. Its value is a JavaScript object with the component's data, or state. When the data changes, Alpine updates everything on the page that depends on it. Such data is called reactive.

Data

The example code in this course goes into the <body> of index.html. Let us start the to-do list with one field:

<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
 
<div x-data="{ title: 'My tasks' }">
  <h2 x-text="title"></h2>
</div>

Below the example the heading "My tasks" appears. The title property is available to every directive inside the <div>.

Methods

The object can hold functions. Inside a method the component's data is reached through this:

<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
 
<div x-data="{
  tasks: ['Buy milk', 'Call Oleg'],
  addTask() {
    this.tasks.push('New task');
    console.log(this.tasks.length);
  }
}">
  <button x-on:click="addTask()">Add</button>
  <p x-text="tasks.join(', ')"></p>
</div>

Each click adds a string to the array: the text below the button grows, and the console under the example prints the new number of tasks — 3, 4 and so on. Alpine notices both assignments and push() calls.

Getters

A value computed from other data is written as a getter — a method with the get keyword:

<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
 
<div x-data="{
  tasks: ['Buy milk', 'Call Oleg'],
  get count() {
    return this.tasks.length;
  }
}">
  <p>Tasks: <span x-text="count"></span></p>
</div>

The page shows "Tasks: 2". The getter is recalculated automatically when the tasks array changes.

Nested components

A component inside another component sees the outer data. When names clash, the nearest one wins:

<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
 
<div x-data="{ owner: 'Anna', title: 'Work' }">
  <div x-data="{ title: 'Home' }">
    <p x-text="owner + ': ' + title"></p>
  </div>
</div>

The page shows "Anna: Home". An empty x-data with no value is also allowed: use it when the directives on an element need no data.

Common mistake

Writing methods in x-data as arrow functions:

<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
 
<div x-data="{ count: 0, add: () => this.count++ }">
  <button x-on:click="add()">+1</button>
  <span x-text="count"></span>
</div>

An arrow function has no this of its own, so the number never changes. Write methods in the short form add() { this.count++ }.

Thanks for reading!

Donate to the site — we work hard for you.