Appearance
BaseForm
BaseForm is a TypeScript base class for Vue forms that gives you:
- Type-safe form state
- Dirty and touched tracking
- Validation and error mapping
- Payload transformations
- Optional persistence
- Array helpers and file handling
- Stable property-aware array item wrappers for reorderable UIs
- Opt-in nested object fields via
PropertyAwareObject
Getting Started
Minimal form class:
ts
import { BaseForm, type PersistenceDriver, SessionStorageDriver } from '@blueprint-ts/core/vue/forms'
import { RequiredRule, ValidationMode } from '@blueprint-ts/core/vue/forms/validation'
interface FormState {
name: string
email: string
}
interface RequestPayload {
name: string
email: string
timestamp: string
}
export class MyForm extends BaseForm<RequestPayload, FormState> {
protected override append: string[] = ['timestamp']
protected override ignore: string[] = []
protected override errorMap: { [serverKey: string]: string | string[] } = {}
public constructor() {
super(
{ name: '', email: '' },
{ persist: true, persistSuffix: 'optional-suffix' }
)
}
protected override getPersistenceDriver(suffix?: string): PersistenceDriver {
return new SessionStorageDriver(suffix)
}
protected override defineRules() {
return {
name: { rules: [new RequiredRule<FormState>('Name is required')] },
email: {
rules: [new RequiredRule<FormState>('Email is required')],
options: { mode: ValidationMode.DEFAULT }
}
}
}
protected getTimestamp(): string {
return new Date().toISOString()
}
}Component usage:
vue
<template>
<form @submit.prevent="submitForm">
<div>
<label>Name</label>
<input v-model="form.properties.name.model.value" />
<div v-if="form.properties.name.errors.length" class="error">
{{ form.properties.name.errors[0] }}
</div>
</div>
<div>
<label>Email</label>
<input v-model="form.properties.email.model.value" />
<div v-if="form.properties.email.errors.length" class="error">
{{ form.properties.email.errors[0] }}
</div>
</div>
<button type="submit" :disabled="!form.isDirty()">Submit</button>
<button type="button" @click="form.reset()">Reset</button>
</form>
</template>
<script setup lang="ts">
import { MyForm } from './MyForm'
const form = new MyForm()
async function submitForm() {
if (!form.validate(true)) return
const payload = form.buildPayload()
await api.submitForm(payload)
}
</script>