What is a component?
A component is a self-mounting, reusable UI unit. Every component extends Component, which extends BaseComponent.
Constructing a component creates and mounts its root element immediately (at mountTarget) — but it isn't rendered until render() runs, either called by hand or via a parent's registerChildren().
What a component owns
- A render pipeline —
onBeforeRender()→ sanitized nodes fromgenerateTemplate()→ mountdata-component/data-catalogchildren → hydratedata-i18n/data-pipeattributes and drop emptydata-optionalelements → binddata-eventlisteners →onAfterRender(). Runs the same way on every render, not just the first. See What lifecycle hooks are available?. - Two independent data channels —
configfeedstemplateFn(withdefaults/normalizeKeysmerging), whileprops+data-bindhandle form-field binding. See How do I pass data to a component?. - Child composition —
registerChildren()mounts nested components (data-component) or repeated lists (data-catalog), re-run on every render. Children are recreated each time unless given akeepvalue (or akeepByfor catalogs), which keeps them and their DOM state across the parent's re-renders. See How do I register child components?. - DOM events —
data-event="click:_handler"attributes are bound/rebound automatically each render and torn down ondestroy(). See How do I handle DOM events?. - Automatic sanitization — rendered HTML is sanitized according to
trustLevelbefore it reaches the DOM. See How do I control HTML sanitization?. - Self-cleanup —
destroy()unbinds DOM events, unsubscribes everyAppEventBussubscription made viathis.listen(...), recursively destroys all tracked children, then removes the element.
Component vs. view
Component and View are siblings — both extend BaseComponent.
A component is small, reusable, and embeddable anywhere a parent component or view mounts it; it isn't tied to a route, and application code constructs it directly (new SomeComponent(el, config)). Components also work without the router: main.ts can mount one into any element of the page (new SomeComponent(el, config).render()) and never call AppRouter, e.g. for a widget in an existing page or a browser extension popup.
Nutin favors composing many small, focused components rather than a few large ones, orchestrated by parent components and, ultimately, a view.
Why aren't components Web Components?
Web Components come with their own model: elements registered globally by tag name, shadow DOM, data passed through attributes and properties, and a lifecycle driven by the browser connecting and disconnecting the element.
A Nutin component is a plain class that renders into an element of the page, in the light DOM.
Web Components still work inside Nutin templates, but Nutin doesn't force you to adopt them. Your markup stays plain HTML, styled by your stylesheets, and data is passed as constructor arguments.
See How to use a11y-elements? for an usage example of custom elements inside Nutin.