-
I've been using AlpineJS for a while with I'm a bit confused as to which one is intended to be used for creating reusable components. From Extending/Simple example, we have the following directive: Alpine.directive("directive-uppercase", (el) => {
el.textContent = el.textContent.toUpperCase();
}); The exact behaviour can be replicated with Alpine.data: Alpine.data("data_uppercase", () => ({
init() {
this.$el.textContent = this.$el.textContent.toUpperCase();
},
})); Following the above example, many other common components can be created using both
EDIT: Real life example of a custom Show codeAlpine.directive("number-input", (el) => {
const inputNumber = el.querySelector("[data-input-number-input]");
const incBtn = el.querySelector("[data-input-number-increment]");
const decBtn = el.querySelector("[data-input-number-decrement]");
let interval;
incBtn.addEventListener("mousedown", () => {
interval = setInterval(() => {
inputNumber.stepUp();
}, 50);
});
incBtn.addEventListener("mouseup", () => clearInterval(interval));
decBtn.addEventListener("mousedown", () => {
interval = setInterval(() => {
inputNumber.stepDown();
}, 50);
});
decBtn.addEventListener("mouseup", () => clearInterval(interval));
});
Alpine.data("number_input", () => ({
interval: null,
// called with @mousedown="stepDown"
stepDown() {
this.interval = setInterval(() => {
this.$refs.inputNumber.stepDown();
}, 50);
},
// called with @mousedown="stepUp"
stepUp() {
this.interval = setInterval(() => {
this.$refs.inputNumber.stepUp();
}, 50);
},
// called with @mouseup="clearInterval"
clearInterval() {
clearInterval(this.interval);
},
})); |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 4 replies
-
Alpine.data is a factory to generate data scopes that you can use into x-data so you don't have your variables and methods scattered into an html tag (and you don't need to redefine them so yeah, it's kinda facilitating the creation of reusable components). It happens to have an init method that runs when you mount the component but it's not the reason why it exists. Your example is not really a reusable component, you just transform something into uppercase and it's more suitable as a directive since you don't have any data at all. |
Beta Was this translation helpful? Give feedback.
I would probably still model it as a directive. The boolean itself could come from somewhere else (like x-show) or if it's not relevant externally, you can bind an internal state (see the ui folder).
Alpine.data is meant to define data, not behaviours. However, as you said, you can probably achieve stuff by using init, if that comes easier for you, you should just use whatever makes you more productive.