Intro to Components
Components are the building blocks of WildflowerJS applications. They encapsulate state, behavior, and templates into reusable, self-contained units declared entirely in HTML.
Defining a Component
Components are defined using wildflower.component() and declared in HTML with data-component:
<div data-component="user-card">
<h3 data-bind="displayName"></h3>
<p data-bind="user.email"></p>
<button class="btn btn-primary" data-action="updateUser">Update User</button>
</div>
wildflower.component('user-card', {
state: {
user: { name: 'John Doe', email: 'john@example.com' },
isLoading: false
},
computed: {
displayName() {
return this.user.name || 'Anonymous'
}
},
updateUser() {
const names = ['Alice Smith', 'Bob Johnson', 'Carol Williams', 'David Brown']
const emails = ['alice@example.com', 'bob@example.com', 'carol@example.com', 'david@example.com']
const index = Math.floor(Math.random() * names.length)
this.user = {
name: names[index],
email: emails[index]
}
},
init() {
console.log('User card initialized:', this.id)
}
})
Component Definition
A component definition can include any of these properties:
| Property | Type | Description |
|---|---|---|
state |
Object | Reactive data properties. See State Management |
computed |
Object | Derived values from state. See Computed Properties |
props |
Object | Parent-to-child data passing. See Props |
watch |
Object | React to specific state or store changes. See Communication |
subscribe |
Object/Array | Declare store dependencies. See Communication |
init(), destroy(), … |
Functions | Lifecycle hooks. See Lifecycle Hooks |
beforeInit() |
Function | Runs before bindings are processed. See Lifecycle Hooks |
beforeUpdate() |
Function | Runs before DOM updates. See Lifecycle Hooks |
onError() |
Function | Error handler for the component. See Error Boundaries |
onPropsChange() |
Function | Runs when received props change. See Props |
| Action methods | Functions | Event handlers referenced by data-action. See Event Handling |
Component Instance Properties
Every component instance has access to these properties via this:
| Property | Type | Description |
|---|---|---|
this.id |
String | Unique component identifier |
this.element |
HTMLElement | Component's root DOM element |
this.state |
Object | Reactive state container |
this.props |
Object | Read-only props passed from parent |
this.computed |
Object | Computed property values |
this.stores |
Object | Subscribed store instances (when using subscribe) |
this.subscribe() |
Function | Programmatic state subscription |
this.emit() |
Function | Child-to-parent communication. See Communication |
this.$el() |
Function | jQuery-like DOM helper. See DOM Helpers |
this.find() |
Function | Query selector within component: this.find('.btn') |
this.findAll() |
Function | Query selector all within component |
this.closest() |
Function | Find closest ancestor matching selector |
this.update() |
Function | Batch state updates: this.update({ count: 1, name: 'x' }) |
this.pools |
Object | Declared pool handles — this.pools.enemies.add({...}) — see Entity Pools |
this.pool() |
Function | Imperative pool access — this.pool('enemies') — backward compatible |
this.parent |
Object | Parent component's context (or null) |
this.listItem |
Object | List item data when inside a data-list (or null) |
Component Composition
Components nest naturally in HTML. Each manages its own state independently:
<div data-component="dashboard">
<header data-component="app-header"></header>
<main>
<aside data-component="sidebar-nav"></aside>
<section data-component="main-content"></section>
</main>
<footer data-component="app-footer"></footer>
</div>
Dynamic Component Creation
Components can be created programmatically and added to the DOM at runtime:
const element = document.createElement('div')
element.setAttribute('data-component', 'notification-toast')
document.getElementById('toasts').appendChild(element)
// Tell the framework to initialize the new component
wildflower.scan(element)