Action Log
The Bowling Alley Analogy
We'll use a bowling alley to understand these three Alpine.js magic properties:
- $el is the current lane you're interacting with. It refers to the element the directive is on.
- $refs are the named equipment in your area, like the 'ball return' or 'pinsetter'. You access them by name.
- $root is the entire alley (your component boundary). It allows you to affect the whole area at once.
1. $el: The Current Lane
$el refers to the DOM element the Alpine directive is attached to. It's like pointing at the specific lane you're on and saying "this one." In event handlers, it's the element that triggered the event.
Demonstration:
Click the button below. The action will use $el to modify the button itself.
Code Example
<!-- The button modifies itself using $el -->
<button @click="lightUpLane($el)">
This is Lane 5
</button>
<script>
Alpine.data('elDemo', () => ({
lightUpLane(element) {
// 'element' is the DOM node passed via $el
this.$store.statusLog.add('$el: Changing the element itself.');
element.textContent = 'LANE 5 IS ACTIVE!';
element.classList.add('bg-green-500', 'text-white');
element.disabled = true;
},
reset() { ... }
}));
</script>
2. $refs: Named Equipment
$refs lets you access any element within your component that has an x-ref attribute. It's like having a control panel where you can press a button to operate a specific, named piece of equipment, no matter where it is.
Lane 6 Control Panel
Code Example
<!-- Name the equipment with x-ref -->
<div x-ref="pinsetter">...</div>
<div x-ref="ballReturn">...</div>
<!-- Control it from anywhere in the component -->
<button @click="activatePinsetter()">Activate</button>
<script>
Alpine.data('refsDemo', () => ({
activatePinsetter() {
this.$store.statusLog.add('$refs: Accessing pinsetter.');
// Access the named element via this.$refs
this.$refs.pinsetter.classList.add('bg-yellow-200');
this.$refs.pinsetter.querySelector('span').textContent = '...';
},
reset() { ... }
}));
</script>
3. $root: The Entire Alley
$root refers to the root element of the component (the element with x-data). It's the "loudspeaker" for your component. An action can affect the entire area, changing the general state or appearance of all elements inside it.
Alley-Wide Controls
Code Example
<!-- The component root -->
<div x-data="rootDemo">
<!-- Button to trigger the change -->
<button @click="startCosmicBowling()">Go Cosmic</button>
<!-- Other elements inside the component -->
<div class="lane-box">...</div>
</div>
<script>
Alpine.data('rootDemo', () => ({
startCosmicBowling() {
this.$store.statusLog.add('$root: Changing the whole alley.');
// 'this.$root' is the div with x-data
this.$root.classList.add('bg-gray-900');
},
resetAlley() { ... }
}));
</script>