How to Write Alpine.js Components
How to Write Alpine.js Components
When using Alpine.js, you may have encountered the challenge of how to structure components. Unlike Vue or React which are component-first, Alpine’s documentation keeps componentization relatively subtle.
Here, we provide two approaches for writing components in Alpine.js. You can consider both methods and choose according to your preference.
Morph
The official Alpine.js site offers a tool called Morph that can be used to achieve component functionality.
Firstly, add this plugin above where you normally include Alpine, as follows:
<script src="libs/alpine.morph.min.js" defer></script>
<script src="libs/alpine.min.js" defer></script>
<script defer src="components/sc-loading.js"></script>
The CDN link is CDN. Download it to your server to ensure proper use by domestic users.
The sc-loading.js
file contains the component code.
Write it like this:
Alpine.morph(
document.querySelector('sc-loading'),
`
<div class="fixed top-0 left-0 w-full h-full bg-gray-900 bg-opacity-50 z-50 flex items-center justify-center" x-show="isLoading" x-transition>
<span class="loading loading-ring loading-lg"></span>
</div>
`
)
This is a loading component using TailwindCSS.
You can see that it can directly use Alpine variables within the same scope, such as isLoading
, which is defined in the corresponding HTML structure.
HTML structure:
<div x-data="indexData">
...
<sc-loading></sc-loading>
</div>
indexData
:
Alpine.data('indexData', () => ({
isLoading: false,
}))
Business Logic Handling
Handling business logic is straightforward; you can proceed as usual without extra attention.
this.isLoading = true;
this.isLoading = false;
Custom Directives
Example usage:
Alpine.directive('loadmore', (el, { expression }, { evaluateLater }) => {
const _fn = evaluateLater(expression);
let isLoading = false;
let lastScrollTime = 0;
const THROTTLE_DELAY = 200;
el.addEventListener('scroll', () => {
const now = Date.now();
if (now - lastScrollTime < THROTTLE_DELAY || isLoading) return;
const scrollBottom = el.scrollHeight - el.scrollTop - el.clientHeight;
if (scrollBottom <= 50) {
isLoading = true;
lastScrollTime = now;
_fn().finally(() => {
isLoading = false;
});
}
});
});
<div x-loadmore="onLoadMore"></div>
This can be quite complex, but the advantage is high customizability. For detailed explanations, refer to the official documentation. Here are some key points:
el
: The mounted element.expression
: The expression following the directive, which can be a variable or function. UseevaluateLater
to handle it accordingly.evaluateLater
: A utility that converts expressions into functions. There are two types of returned functions: one returns the passed expression function, while the other returns a function that generates an expression variable. The former can be used as an expression directly. The latter needs to be used witheffect
to implement listening effects. Check the documentation for more details.
Conclusion
These two solutions cover most scenarios you might encounter when working with Alpine.js. Other hacky methods are not discussed here. Thank you for reading, and I hope this helps you.
Comments
Post a Comment