Use Cases
Modal Login Form
Create a <ModalLoginForm> component with <VueFinalModal> and TailwindCSS.
A login form inside a modal. The form is validated with Vorms, and the modal closes once the form is submitted.
Preview
Preview.vue
<script setup lang="ts">
import type { FormData } from './LoginFormVorms.vue'
import { useModal } from 'vue-final-modal'
import ModalLoginForm from './ModalLoginForm.vue'
const submitted = ref('nothing yet')
const { open, close } = useModal({
component: ModalLoginForm,
attrs: {
onSubmit(formData: FormData) {
submitted.value = JSON.stringify(formData)
close()
},
},
})
</script>
<template>
<div class="flex flex-wrap items-center justify-center gap-3">
<VButton @click="() => open()">
Open Modal
</VButton>
<output class="inline-flex items-center gap-1.5 rounded-md border border-default px-2 py-1 text-sm text-muted">
Submitted: <span class="font-medium text-highlighted">{{ submitted }}</span>
</output>
</div>
</template>
<ModalLoginForm> component
<script setup lang="ts">
import type { FormData } from './LoginFormVorms.vue'
import { useId } from 'vue'
import { VueFinalModal } from 'vue-final-modal'
import LoginFormVorms from './LoginFormVorms.vue'
const emit = defineEmits<{
(e: 'submit', formData: FormData): void
}>()
const titleId = useId()
</script>
<template>
<VueFinalModal
class="flex justify-center items-center"
content-class="relative w-full max-w-xs mx-4 p-4 rounded-lg bg-white dark:bg-gray-900 border dark:border-gray-700"
content-transition="vfm-fade"
overlay-transition="vfm-fade"
:aria-labelledby="titleId"
>
<h1 :id="titleId" class="text-2xl mb-4">
Login
</h1>
<LoginFormVorms @submit="formData => emit('submit', formData)" />
</VueFinalModal>
</template>
<LoginFormVorms> component
<script setup lang="ts">
import { useForm } from '@vorms/core'
export type FormData = {
account: string
password: string
remember: boolean
}
const emit = defineEmits<{
(e: 'submit', formData: FormData): void
}>()
const { register, errors, handleSubmit } = useForm({
initialValues: {
account: '',
password: '',
remember: false,
},
onSubmit(values) {
emit('submit', values)
},
})
const { value: account, attrs: accountAttrs } = register('account', {
validate(value) {
if (!value)
return 'account is required!'
},
})
const { value: password, attrs: passwordAttrs } = register('password')
const { value: remember, attrs: rememberAttrs } = register('remember')
</script>
<template>
<form class="flex flex-col gap-4" @submit="handleSubmit">
<div>
<input
v-model="account"
class="w-full px-2 py-1 border dark:border-gray-700 rounded-lg bg-transparent"
type="text"
placeholder="Account"
v-bind="accountAttrs"
>
<div v-show="'account' in errors" class="mt-0.5 text-red-500">
{{ errors.account }}
</div>
</div>
<input
v-model="password"
class="w-full px-2 py-1 border dark:border-gray-700 rounded-lg bg-transparent"
type="password"
placeholder="Password"
v-bind="passwordAttrs"
>
<div class="flex items-center gap-1">
<input
id="remember"
v-model="remember"
class="accent-[#41b883]"
type="checkbox"
v-bind="rememberAttrs"
>
<label for="remember">remember</label>
</div>
<input type="submit" value="Submit" class="w-full px-2 py-1 rounded-lg border border-[#41b883] bg-[#41b883] text-white cursor-pointer">
</form>
</template>