Control rendering identity and form scope
Keep list identity stable, skip unchanged work and choose the form scope for each field.
The example reorders rows, swaps the selected profile and edits local and validated fields. The comparison below assigns each mechanism to that work.
Table of contents
Main APIs
- mount
- Starts a Valyrian.js application on a DOM target.
- FormStore
- Coordinates form state, validation, transforms and submission.
tsximport { mount } from "valyrian.js";
import { FormStore } from "valyrian.js/forms";
type Row = { id: string; name: string };
const rows: Row[] = [
{ id: "arya", name: "Arya" },
{ id: "sam", name: "Sam" },
];
const localFilter = { query: "" };
const profileForm = new FormStore({
state: { email: "" },
schema: {
type: "object",
properties: { email: { type: "string", format: "email" } },
required: ["email"],
},
onSubmit: async () => {},
});
const RenderingChoices = {
selectedId: "arya",
reverseRows() {
rows.reverse();
},
selectProfile(id: string) {
this.selectedId = id;
},
view() {
const selected = rows.find((row) => row.id === this.selectedId) || rows[0];
return (
<main>
<button onclick={() => this.reverseRows()}>Reverse rows</button>
<ul v-for={rows}>
{(row: Row) => (
<li key={row.id}>
<button onclick={() => this.selectProfile(row.id)}>
{row.name}
</button>
</li>
)}
</ul>
<section v-keep={this.selectedId}>
Selected profile: {selected.name}
</section>
<label>
Local filter
<input name="query" v-model={localFilter} />
</label>
<form v-form={profileForm}>
<label>
Validated email
<input name="email" type="email" v-field={profileForm} />
</label>
<button type="submit">Save profile</button>
</form>
</main>
);
},
};
mount("body", RenderingChoices);Starting point
Start with a mounted view that contains a reorderable list, one subtree selected by identifier and both a local field and a validated form.
Choose each mechanism by task
- key
- Use a stable identifier when list order can change so each rendered sibling keeps the same identity.
- v-keep
- Use the value that represents the subtree input. An unchanged guard skips that subtree during the patch.
- v-model
- Use it for lightweight local fields whose values live in one local object.
- FormStore
- Use it when the form needs schema validation, clean or format transforms, submission state or reusable behavior.
Action
Reverse the keyed list and select another profile. Edit the local filter through v-model and the validated email through the FormStore field binding.
Observable result
The list renders in the new order with the same stable identifiers. Changing selectedId allows the guarded profile subtree to render the newly selected name. Each form field writes to its chosen state layer.
Continue with forms
Limit
A stable `v-keep` guard skips that subtree during a patch. Change the guard when the subtree input must render again.