Advanced x-data Patterns
Reusable, parameterized, and composable components.
Reusable & Composable Components
As your Alpine app grows, you'll want to avoid repeating component logic. Alpine.data() and Alpine.bind() let you define components that can be reused, parameterized, and even composed together using mixins.
Parameterized Components
Data factories can accept arguments, allowing you to customise each instance.
Alpine.data('modal', (initialOpen = false, size = 'medium') => ({
open: initialOpen,
size: size,
init() {
console.log('Modal initialized with size:', size)
},
close() { this.open = false }
}))
// Usage: <div x-data="modal(true, 'large')">Nested Components & Communication
Nested x-data components have independent scopes. They can communicate using $dispatch (for child→parent) and $store (for any shared state).
Alpine.merge() for Mixins
You can mix multiple data factories into one using Alpine.merge(). This is similar to mixins in Vue.
Alpine.data('togglable', () => ({ open: false, toggle() { this.open = !this.open } }))
Alpine.data('closable', () => ({ close() { this.open = false } }))
Alpine.data('dialog', () => ({
...Alpine.merge(Alpine.data('togglable'), Alpine.data('closable'))
}))Extracting Business Logic
For complex logic, keep your Alpine.data() factories clean by extracting pure functions or services. This makes unit testing trivial.
// utils.js
export function formatPrice(amount) {
return '$' + amount.toFixed(2)
}
// alpine-component.js
Alpine.data('product', () => ({
price: 9.99,
get formattedPrice() { return formatPrice(this.price) }
}))💡 Tip
Use TypeScript with Alpine? Export your data factories as typed functions for better auto‑completion and safety.