A high-performance, schema-driven form generation engine for Vue 3, designed for complex enterprise data models.
- High Performance: Optimized rendering engine with pre-computed schema resolution and layout bindings.
- Advanced Data Binding:
- JSONPath: Full support for absolute (
$) and relative (@) paths. - Parent Traversal: Use
^to access parent contexts (e.g.,^.prop).
- JSONPath: Full support for absolute (
- Robust Validation:
- Metadata-Driven: Validators are self-describing with usage metadata.
- i18n Built-in: Native integration with
vue-i18nfor localized error messages and validator definitions. - Engine-Level Gating: Prevents submission if any field is invalid.
- Framework Agnostic: Decoupled from any specific UI library. Bring your own Shadcn, Vuetify, or unstyled HTML components.
- Modular Architecture:
- SchemaForm: Root orchestrator managing state and layout.
- SchemaRenderer: Recursive component for efficient tree rendering.
- Registry: Dependency injection system for components and validators.
- TypeScript First: Strict typing for schemas, validators, and engine context.
The engine is framework-agnostic. You must inject your UI components (theme) via the components prop.
<template>
<SchemaForm
:schema="schema"
:components="theme"
v-model="formData"
@submit="handleSubmit"
/>
</template>
<script setup lang="ts">
import { ref } from "vue";
import { SchemaForm } from "@operativeit/schema-form";
// Import your local theme definition (map of component names -> Vue components)
import { ShadcnTheme } from "@/components/schema-form/themes/shadcn";
const theme = ShadcnTheme;
const formData = ref({
user: {
name: "John Doe",
email: "",
},
});
const schema = [
{
component: "Text", // Matches key in your Theme object
model: "$.user.name",
label: "Name",
rules: "required|min:3",
},
{
component: "Text",
model: "$.user.email",
label: "Email",
rules: "required|email",
},
];
const handleSubmit = () => {
console.log("Form Submitted:", formData.value);
};
</script>The core brain of the system. It handles:
- State Management: Wraps your data model in a reactive context.
- Path Resolution:
$: Root@: Current Context^: Parent Context (Multi-level supported, e.g.,^^.prop)
- Query/Update: Uses optimized JSONPath lookups for reading and writing deep values.
An optimized recursive component that:
- Pre-computes paths and bindings to minimize re-renders.
- Iterates over schema definitions efficiently.
- Resolves component definitions from the registry dynamically.
Validation is decoupled and metadata-driven.
- Validators: Pure functions located in
utils/validators.ts. - Metadata: Each validator exports descriptive metadata (label, options) used by the Form Builder.
- Internationalization: Error messages and metadata use
t()keys for full localization.
| Symbol | Meaning | Example |
|---|---|---|
$ |
Root | $.store.book[0] |
@ |
Current | @.title (inside book object) |
^ |
Parent | ^.category (sibling of parent array) |
^^ |
Grandparent | ^^.storeName |
Validators can be added via the module system. Create a file in utils/validators/ and it will be auto-registered.
// utils/validators/myValidator.ts
export const myValidator = (value, options) => {
return value === "correct" ? undefined : "Error!";
};
export const metadata = {
label: "My Validator",
description: "Checks if value is 'correct'",
};
export const extend = (registry) => {
registry.myValidator = myValidator;
};a a