Vue
Step-by-step integration of the components into a Vue 3 or Nuxt application.
Vue 3 works with custom elements natively: it sets DOM properties, so objects and arrays need no wrapper. The one thing it must be told is which tags are custom elements, otherwise the compiler warns about unknown components.
1. Install
2. Tell the compiler about the tags
Every tag starts with tuix-, so one rule covers the whole library.
3. Register the elements
Import the library once, where the app is created:
The stylesheet also pulls Rubik in from the Tuix CDN.
In Nuxt, the import has to stay on the client, because the elements extend
HTMLElement, which does not exist while the server renders:
The .client suffix is what keeps it out of the server bundle. Server-rendered
markup still contains the tags; they upgrade when the plugin runs.
4. Use them
Properties vs attributes
With v-bind, Vue checks whether the name exists on the element and sets it as
a property when it does. So bind with the property's own spelling:
The .prop modifier forces it where necessary: :options.prop="countries".
Events
Every event binds with @ under its own name, camelCase ones included, once
isCustomElement marks the tag as an element:
@customClick works because Vue keeps the case of a listener name that contains
a capital letter when the tag is an element rather than a component: "these may
be custom elements' custom events", as the compiler puts it. Every other name is
lowercase already, so nothing has to be spelled differently from the
Events reference.
Do not reach for a dynamic name (@[clickEvent]) for this. It is the one form that breaks: a dynamic name compiles
to onCustomClick, which Vue hyphenates to custom-click, and the handler then never runs. Bind @customClick
directly.
A template ref works too, and reads better when several handlers are involved:
v-model
v-model does not work on these elements, because they emit on-change
instead of update:modelValue. The value plus the handler works, as does
wrapping the element in a small Vue component that exposes modelValue:
Troubleshooting
| Symptom | Cause |
|---|---|
Failed to resolve component: tuix-button | isCustomElement is not configured for the build tool in use |
HTMLElement is not defined during a Nuxt build | The library is imported on the server; move it into a .client plugin |
| A camelCase event never fires | It was bound with a dynamic name; bind @customClick directly |
| An array prop arrives as a string | It was written as a static attribute instead of :bound |
| The field never changes | The value is not written back from the change handler |