1. Initial Setup
In this example we're using Vite to develop the project, but you can use whatever developer setup you want.
npm init vite@latest
✔ Project name: … todo-app
✔ Select a framework: › vanilla
✔ Select a variant: › vanilla-ts
2
3
4
5
Then, cd todo-app, npm install the packages and run npm run dev to start your server. Visit http://localhost:3000 to see the Hello Vite starting point.
To start with muban, install these two packages;
npm i @muban/muban @muban/template
Our first component
Our first component will be the App component, which will be the root of our application. To keep things simple, we are only going to render a custom title in the template, with no logic in the component itself.
Template file
Create a src/components/App/App.template.ts for our template;
import { html, ComponentTemplateResult } from '@muban/template';
export type AppTemplateProps = {
title?: string;
};
export function appTemplate({ title = 'Todos' }: AppTemplateProps): ComponentTemplateResult {
return html`
<div data-component="app">
<h1>${title}</h1>
</div>
`;
}
2
3
4
5
6
7
8
9
10
11
12
13
Here we have done the following;
- We import
htmlfrom@muban/template, a helper to write our tagged template strings. - We define a
typefor our template props. We always pass our props as an object. Optional props can be marked with a?in the type, and potentially given a default value when destructuring them. - We create the template itself, which is a normal function, receiving the props as an object, and returning a
ComponentTemplateResult(which is astring, or anArrayofstrings). Which is what thehtmlhelper will return. - We define our root element, adding a
data-componentattribute withapp, to link it to our TypeScript Component file later. Each template should always have a single root element, that should have a matchingdata-componentattribute. Besides linking it to our logic, it can also be used to style our components (as apposed to classnames). - We use our
titleprop in our html, as you would use any variable in a template string.
Initial State
When rendering any template in Muban, think of it as the initial state of your application or component. Even without executing any component initialisation, your templates should reflect what would be rendered on the server. This means that your templates should not include any "interaction logic". The output should be a static string.
Component file
Now that we have our template, let's create the Component itself by creating src/components/App/App.ts.
import { defineComponent } from '@muban/muban';
export const App = defineComponent({
name: 'app',
setup() {
console.log('App Running...');
return [];
},
});
2
3
4
5
6
7
8
9
Here we have done the following:
- We import
defineComponent, which is our factory function to create Muban Components. - As options, we give it a name,
appin this case. This should match thedata-componentattribute from our template file. - Every component has a
setupfunction, where it returnsbindings. This is the "minimum required" code to be in there, we'll add more things later. - For now, we're adding a
console.logto check if our component is correctly initialized.
Component Initialisation
A component is only initialized when there is an html element with the matching data-componentattribute value present in the DOM.
Additionally, the Component file should be registered to a "parent component", or globally to the Muban "application".
In the parent component this can be done by using refComponent for the refs, or using the components array. More on this later.
Rendering the App
Now that we have our first component (a template and logic file), it's time to render it by mounting our Application.
In the main.ts (that was created by Vite), change the code to this:
import './style.css';
import { createApp } from '@muban/muban';
import { App } from './components/app/App';
import { appTemplate } from './components/app/App.template';
const appRoot = document.getElementById('app')!;
const app = createApp(App);
app.mount(appRoot, appTemplate, {
title: 'Todos',
});
2
3
4
5
6
7
8
9
10
11
12
It does the following things:
- Import
createApp, for creating our Muban Application. - Import our component and template files.
- Query the root element of our application.
- Call
createAppby passing ourAppcomponent, which returns theappinstance. mountour application in theappRoot, passing theappTemplateto render the HTML, passing thetitleprop to pass to the template.
If we check the browser, we should see a Todos title, and App Running... in the devtools console.
Development mode
Calling mount with a template + data is normally something we only do in development, or abusing muban to create a client-side-rendered App. The strength of muban lies in working with existing HTML that is rendered on the server.
If you already have HTML on the page, you can leave out the template and data arguments.