Form
Collect and validate form data.
Usage
Use the Form component to validate form data using schema libraries such as Yup, Zod, Joi, Valibot, or your own validation logic.
It works with the FormGroup component to display error messages around form elements automatically.
The form component requires two props:
state
- a reactive object holding the form's state.schema
- a schema object from Yup, Zod, Joi, or Valibot.
INFO
Note that no validation library is included by default, so ensure you install the one you need.
Schema
You can provide a schema from Yup, Zod or Joi, Valibot through the schema
prop to validate the state. It's important to note that none of these libraries are included by default, so make sure to install the one you need.
<script setup lang="ts">
import { ref } from 'vue'
import { object, string, InferType } from 'yup'
const schema = object({
email: string().email('Invalid email').required('Required'),
password: string()
.min(8, 'Must be at least 8 characters')
.required('Required')
})
type Schema = InferType<typeof schema>
const state = ref({
email: undefined,
password: undefined
})
async function submit (event) {
// Do something with event.data
console.log(event.data)
}
</script>
<template>
<s-form
:schema="schema"
:state="state"
@submit="submit"
class="space-y-4"
>
<s-form-group label="Email" name="email">
<s-input v-model="state.email" />
</s-form-group>
<s-form-group label="Password" name="password">
<s-input v-model="state.password" type="password" />
</s-form-group>
<s-button type="submit">
Submit
</s-button>
</s-form>
</template>
Custom validation
Use the validate
prop to apply your own validation logic.
The validation function must return a list of errors with the following attributes:
message
- Error message for display.path
- Path to the form element corresponding to thename
attribute.
INFO
Note that it can be used alongside the schema
prop to handle complex use cases.
<script setup lang="ts">
import {reactive} from "vue";
const state = reactive({
email: undefined,
password: undefined
})
const validate = (state: any) => {
const errors = []
if (!state.email) errors.push({path: 'email', message: 'Required'})
if (!state.password) errors.push({path: 'password', message: 'Required'})
return errors
}
async function onSubmit(event) {
// Do something with data
console.log(event.data)
}
</script>
<template>
<SForm :validate="validate" :state="state" class="space-y-4" @submit="onSubmit">
<SFormGroup label="Email" name="email">
<SInput v-model="state.email"/>
</SFormGroup>
<SFormGroup label="Password" name="password">
<SInput v-model="state.password" type="password"/>
</SFormGroup>
<SButton type="submit">
Submit
</SButton>
</SForm>
</template>