52
loading...
This website collects cookies to deliver better user experience
Go
processing the page creation like SSR.Your new, lightweight, Javascript framework
x-data
attribute, simple ha!? To reuse component's logic we decide to create a single JS file that represents logic and state of each component. Let's see a simple example of a file with counter
.export function counter() {
return {
count: 0,
reset() {
this.count = 0;
},
increment() {
this.count++;
},
decrement() {
this.count--;
}
}
}
counter
component with count
attribute and 3 operations: reset, increment and decrement. In HTML side we need to attach its function with our component, like:<div x-data="counter" class="box-counter">
<span class="lbl-counter"
:class="{'lbl-counter-red': count < 0, 'lbl-counter-blue': count > 0}"
x-text="count">0</span>
<div class="">
<button type="button" class="btn-counter" @click="increment"> Increment </button>
<button type="button" class="btn-counter" @click="reset">Reset</button>
<button type="button" class="btn-counter" @click="decrement"> Decrement </button>
</div>
</div>
div
tag has an attribute x-data
that has value counter
. So Alpine does the magic here linking both (HTML and Javascript). index.ts
that will exports all components necessary to that page. On image below you can see POC structure:shared
that contains all shared components between the pages, like: menu, navbar, etc. Let's explore the demo page.index.ts
file for this page is shown below:import menu from '../shared/menu'
import counter from './counter'
import todos from './todos'
export {
menu,
counter,
todos
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Demo</title>
<link rel="stylesheet" href="assets/global.css" />
</head>
<body>
<nav x-data="menu" class="nav-header">
...
</nav>
<div x-data="counter" class="box-counter">
...
</div>
<div x-data="todos" class="todoapp">
...
</div>
</body>
</html>
loader
function that solve it for us. The loader function is shown below:export async function loader(modules) {
const { default: alpinejs } = await import('https://cdn.skypack.dev/alpinejs')
let promises = modules.map((mod) => import(mod))
return Promise.all(promises).then(values => {
console.debug('Alpine', alpinejs.version)
values.forEach(module => {
Object.keys(module).forEach(attr => {
let data = module[attr]();
alpinejs.data(attr, () => data);
})
})
alpinejs.start();
})
}
<script defer type="module">
import { loader } from './assets/loader.js'
loader(['/dist/demo/index.js']).catch(err => console.error(err))
</script>
/dist/demo/index.js
. Its a standard we decided to our application and works fine for us. We are using rollup
to transpile our Typescript code and bundle it.