Reactivity
Studio writes this format for you. The Data panel and the Inspector's Logic tab ( Logic ) generate everything below. This page documents the model if you want to hand-edit or understand it.
Template literal syntax
${}
is valid
anywhere a string value appears
in the document tree, not only inside
state
. Wherever you write one, the value recomputes when the state it reads changes. All reactivity is powered by
@vue/reactivity
.
A template resolves
state.propertyName
against the current component's reactive proxy, plus the iteration bindings (
$map
,
item
,
index
) where an Array map provides them.
Reactive element properties
{
"tagName": "div",
"textContent": "${state.count} items remaining",
"className": "${state.active ? 'card active' : 'card'}",
"hidden": "${state.items.length === 0}"
}
A binding that throws waits for its data.
State that loads asynchronously reads
null
first, so
${state.posts.length}
throws until the posts arrive. The binding renders nothing in the meantime, logs one console warning, and fills in on its own once the value it reads is valid.
Reactive style properties
{
"tagName": "div",
"style": {
"color": "${state.score > 90 ? 'gold' : 'inherit'}",
"opacity": "${state.loading ? '0.5' : '1'}"
}
}
Reactive attributes
{
"tagName": "button",
"attributes": {
"aria-label": "${state.count} unread messages",
"data-state": "${state.status}"
}
}
How it works
When the compiler encounters
${}
in any string-valued property, it wraps the binding in a reactive effect:
watchEffect(() => {
el.textContent = `${state.count} items remaining`;
});
Dependencies are tracked automatically by Vue when
state.*
properties are read.
Choosing between
$ref
and a template string
Prefer
${}
for a single-use reactive binding, and
$ref
for a signal that is named and reused.
| Pattern | Use when |
|---|---|
{ "$ref": "#/state/label" } |
Binding to a named signal used in multiple places |
"${state.count} items" |
Inline computed binding used in exactly one place |
Computed state
Template strings in
state
become
computed()
values:
{
"state": {
"firstName": "Jane",
"lastName": "Doe",
"fullName": "${state.firstName} ${state.lastName}"
}
}
Reading and writing state from JavaScript
Within
body
strings and external
.js
files, read and write state directly:
// Read
const current = state.count;
// Write
state.count = current + 1;
// Mutate array (Vue tracks mutations)
state.items.push(newItem);
// Mutate nested object
state.user.name = "Alice";
There are no
.get()
or
.set()
calls and no
this
. All component state is reached through
state
.
Prototypes for web APIs
Built-in prototypes for common web APIs:
$prototype |
Web API | Description |
|---|---|---|
Request |
Fetch API | Reactive URL, debounce, abort |
URLSearchParams |
URL API | Computed
.toString() |
FormData |
FormData API | Field population |
LocalStorage |
Storage API | Reactive persistence |
SessionStorage |
Storage API | Session-scoped storage |
IndexedDB |
IDB API | Store creation, CRUD |
Array |
— | Dynamic mapped lists |
Timing
| Value | When |
|---|---|
"client" |
Resolved at runtime in the browser (default) |
"server" |
Resolved at runtime on the server via RPC |
"compiler" |
Resolved at build time, baked into emitted HTML |
Related
State declares the signals a template reads.
Expressions covers what may appear inside
${}.Timing covers when each value resolves.