Demonstrating $el, $refs, and $root using a desktop analogy.
Analogy: The Active Window.
$el refers to the current DOM element. An action inside a "window" can affect that window directly, like bringing it into focus when clicked.
<!-- Button inside a window -->
<button @click="setActive($el)">
Focus Me
</button>
<!-- Logic in Alpine.data -->
setActive(buttonEl) {
const windowEl = buttonEl.closest('.window');
// ...logic to style the 'windowEl'
}
Analogy: Named Applications on a taskbar.
$refs lets you access specific elements marked with x-ref by name. The "taskbar" can open, close, or focus a specific "app window" without being inside it.
<!-- Taskbar button -->
<button @click="toggleApp('terminal')">
Terminal
</button>
<!-- App window with x-ref -->
<div x-ref="terminal" x-show="apps.terminal.visible">
...
</div>
<!-- Logic in Alpine.data -->
toggleApp(appName) {
// this.$refs[appName] is now available
this.apps[appName].visible = !this.apps[appName].visible;
}
Analogy: The Entire System/Desktop.
$root refers to the root element of the component (where x-data is). A nested control, like a "dark mode" switch, can use it to change a class on the entire "desktop".
<!-- The root component -->
<div x-data="desktopSystem" :class="{ 'dark': isDarkMode }">
<!-- Nested control -->
<button @click="$root.classList.toggle('dark'); isDarkMode = !isDarkMode">
Toggle Theme
</button>
</div>
Click the button below to make this the "active window".
This is another window you can bring into focus.
Opened by default. Use the taskbar to toggle my visibility.
x-ref="fileExplorer"> Accessed via $refs.terminal...
> Ready.
x-ref="terminal"This panel is deeply nested, but can control the whole system theme.