AuthForm 작성
Usage
Form 구성 요소 위에 구축 된 AuthForm 구성 요소는 페이지에서 사용하거나 PageCard로 래핑 할 수 있습니다.
<script setup lang="ts">
import * as z from 'zod'
import type { FormSubmitEvent, AuthFormField } from '@nuxt/ui'
const toast = useToast()
const fields: AuthFormField[] = [{
name: 'email',
type: 'email',
label: 'Email',
placeholder: 'Enter your email',
required: true
}, {
name: 'password',
label: 'Password',
type: 'password',
placeholder: 'Enter your password',
required: true
}, {
name: 'remember',
label: 'Remember me',
type: 'checkbox'
}]
const providers = [{
label: 'Google',
icon: 'i-simple-icons-google',
onClick: () => {
toast.add({ title: 'Google', description: 'Login with Google' })
}
}, {
label: 'GitHub',
icon: 'i-simple-icons-github',
onClick: () => {
toast.add({ title: 'GitHub', description: 'Login with GitHub' })
}
}]
const schema = z.object({
email: z.email('Invalid email'),
password: z.string('Password is required').min(8, 'Must be at least 8 characters')
})
type Schema = z.output<typeof schema>
function onSubmit(payload: FormSubmitEvent<Schema>) {
console.log('Submitted', payload)
}
</script>
<template>
<div class="flex flex-col items-center justify-center gap-4 p-4">
<UPageCard class="w-full max-w-md">
<UAuthForm
:schema="schema"
title="Login"
description="Enter your credentials to access your account."
icon="i-lucide-user"
:fields="fields"
:providers="providers"
@submit="onSubmit"
/>
</UPageCard>
</div>
</template>
필드
폼은 fields prop을 기반으로 자체 구성되며 상태는 내부적으로 처리됩니다.
fields Prop을 다음 속성을 가진 오브젝트 배열로 사용합니다.
name: stringXph017xname: stringtype: 'checkbox' | 'select' | 'otp' | 'InputHTMLAttributes['type']'
각 필드에는 입력 구성요소와 적용되는 추가 소품을 결정하는 type 속성이 포함되어야 합니다. checkbox 필드는 Checkbox props를 사용하고, select 필드는 SelectMenu props를 사용하고, otp 필드는 [PinInput](/docs/components/pin-input#props/docs/components/pin-input#props, x) props를 사용합니다. 그리고 다른 모든 타입은 Input props를 사용합니다.
또한 FormField 구성 요소의 모든 속성을 각 필드로 전달할 수 있습니다.
<script setup lang="ts">
import type { AuthFormField } from '@nuxt/ui'
const fields = ref<AuthFormField[]>([
{
name: 'email',
type: 'email',
label: 'Email',
placeholder: 'Enter your email',
required: true
},
{
name: 'password',
type: 'password',
label: 'Password',
placeholder: 'Enter your password',
required: true
},
{
name: 'country',
type: 'select',
label: 'Country',
placeholder: 'Select country',
items: [
{
label: 'United States',
value: 'us'
},
{
label: 'France',
value: 'fr'
},
{
label: 'United Kingdom',
value: 'uk'
},
{
label: 'Australia',
value: 'au'
}
]
},
{
name: 'otp',
type: 'otp',
label: 'OTP',
length: 6,
placeholder: '○'
},
{
name: 'remember',
type: 'checkbox',
label: 'Remember me',
description: 'You will be logged in for 30 days.'
}
])
</script>
<template>
<UAuthForm :fields="fields" class="max-w-sm" />
</template><script setup lang="ts">
import { ref } from 'vue'
import type { AuthFormField } from '@nuxt/ui'
const fields = ref<AuthFormField[]>([
{
name: 'email',
type: 'email',
label: 'Email',
placeholder: 'Enter your email',
required: true
},
{
name: 'password',
type: 'password',
label: 'Password',
placeholder: 'Enter your password',
required: true
},
{
name: 'country',
type: 'select',
label: 'Country',
placeholder: 'Select country',
items: [
{
label: 'United States',
value: 'us'
},
{
label: 'France',
value: 'fr'
},
{
label: 'United Kingdom',
value: 'uk'
},
{
label: 'Australia',
value: 'au'
}
]
},
{
name: 'otp',
type: 'otp',
label: 'OTP',
length: 6,
placeholder: '○'
},
{
name: 'remember',
type: 'checkbox',
label: 'Remember me',
description: 'You will be logged in for 30 days.'
}
])
</script>
<template>
<UAuthForm :fields="fields" class="max-w-sm" />
</template>Title 파일
title prop 을 사용하여 Form 의 제목을 설정합니다.
<script setup lang="ts">
import type { AuthFormField } from '@nuxt/ui'
const fields = ref<AuthFormField[]>([
{
name: 'email',
type: 'text',
label: 'Email'
},
{
name: 'password',
type: 'password',
label: 'Password'
}
])
</script>
<template>
<UAuthForm title="Login" :fields="fields" class="max-w-md" />
</template><script setup lang="ts">
import { ref } from 'vue'
import type { AuthFormField } from '@nuxt/ui'
const fields = ref<AuthFormField[]>([
{
name: 'email',
type: 'text',
label: 'Email'
},
{
name: 'password',
type: 'password',
label: 'Password'
}
])
</script>
<template>
<UAuthForm title="Login" :fields="fields" class="max-w-md" />
</template>설명
description prop을 사용하여 양식에 대한 설명을 설정합니다.
<script setup lang="ts">
import type { AuthFormField } from '@nuxt/ui'
const fields = ref<AuthFormField[]>([
{
name: 'email',
type: 'text',
label: 'Email'
},
{
name: 'password',
type: 'password',
label: 'Password'
}
])
</script>
<template>
<UAuthForm
title="Login"
description="Enter your credentials to access your account."
:fields="fields"
class="max-w-md"
/>
</template><script setup lang="ts">
import { ref } from 'vue'
import type { AuthFormField } from '@nuxt/ui'
const fields = ref<AuthFormField[]>([
{
name: 'email',
type: 'text',
label: 'Email'
},
{
name: 'password',
type: 'password',
label: 'Password'
}
])
</script>
<template>
<UAuthForm
title="Login"
description="Enter your credentials to access your account."
:fields="fields"
class="max-w-md"
/>
</template>Icon
icon prop을 사용하여 form의 아이콘을 설정합니다.
<script setup lang="ts">
import type { AuthFormField } from '@nuxt/ui'
const fields = ref<AuthFormField[]>([
{
name: 'email',
type: 'text',
label: 'Email'
},
{
name: 'password',
type: 'password',
label: 'Password'
}
])
</script>
<template>
<UAuthForm
title="Login"
description="Enter your credentials to access your account."
icon="i-lucide-user"
:fields="fields"
class="max-w-md"
/>
</template><script setup lang="ts">
import { ref } from 'vue'
import type { AuthFormField } from '@nuxt/ui'
const fields = ref<AuthFormField[]>([
{
name: 'email',
type: 'text',
label: 'Email'
},
{
name: 'password',
type: 'password',
label: 'Password'
}
])
</script>
<template>
<UAuthForm
title="Login"
description="Enter your credentials to access your account."
icon="i-lucide-user"
:fields="fields"
class="max-w-md"
/>
</template>공급자
providers prop를 사용하여 양식에 공급자를 추가합니다.
Button 구성 요소에서 variant, color, to 등과 같은 속성을 전달할 수 있습니다.
<script setup lang="ts">
import type { ButtonProps, AuthFormField } from '@nuxt/ui'
const providers = ref<ButtonProps[]>([
{
label: 'Google',
icon: 'i-simple-icons-google',
color: 'neutral',
variant: 'subtle'
},
{
label: 'GitHub',
icon: 'i-simple-icons-github',
color: 'neutral',
variant: 'subtle'
}
])
const fields = ref<AuthFormField[]>([
{
name: 'email',
type: 'text',
label: 'Email'
},
{
name: 'password',
type: 'password',
label: 'Password'
}
])
</script>
<template>
<UAuthForm
title="Login"
description="Enter your credentials to access your account."
icon="i-lucide-user"
:providers="providers"
:fields="fields"
class="max-w-md"
/>
</template><script setup lang="ts">
import { ref } from 'vue'
import type { ButtonProps, AuthFormField } from '@nuxt/ui'
const providers = ref<ButtonProps[]>([
{
label: 'Google',
icon: 'i-simple-icons-google',
color: 'neutral',
variant: 'subtle'
},
{
label: 'GitHub',
icon: 'i-simple-icons-github',
color: 'neutral',
variant: 'subtle'
}
])
const fields = ref<AuthFormField[]>([
{
name: 'email',
type: 'text',
label: 'Email'
},
{
name: 'password',
type: 'password',
label: 'Password'
}
])
</script>
<template>
<UAuthForm
title="Login"
description="Enter your credentials to access your account."
icon="i-lucide-user"
:providers="providers"
:fields="fields"
class="max-w-md"
/>
</template>Separator 문자 입력
separator Prop을 사용하여 공급자와 필드 간에 Separator를 사용자 정의합니다. 기본값은 or입니다.
<script setup lang="ts">
import type { ButtonProps, AuthFormField } from '@nuxt/ui'
const providers = ref<ButtonProps[]>([
{
label: 'Google',
icon: 'i-simple-icons-google',
color: 'neutral',
variant: 'subtle'
},
{
label: 'GitHub',
icon: 'i-simple-icons-github',
color: 'neutral',
variant: 'subtle'
}
])
const fields = ref<AuthFormField[]>([
{
name: 'email',
type: 'text',
label: 'Email'
},
{
name: 'password',
type: 'password',
label: 'Password'
}
])
</script>
<template>
<UAuthForm
title="Login"
description="Enter your credentials to access your account."
icon="i-lucide-user"
:providers="providers"
:fields="fields"
separator="Providers"
class="max-w-md"
/>
</template><script setup lang="ts">
import { ref } from 'vue'
import type { ButtonProps, AuthFormField } from '@nuxt/ui'
const providers = ref<ButtonProps[]>([
{
label: 'Google',
icon: 'i-simple-icons-google',
color: 'neutral',
variant: 'subtle'
},
{
label: 'GitHub',
icon: 'i-simple-icons-github',
color: 'neutral',
variant: 'subtle'
}
])
const fields = ref<AuthFormField[]>([
{
name: 'email',
type: 'text',
label: 'Email'
},
{
name: 'password',
type: 'password',
label: 'Password'
}
])
</script>
<template>
<UAuthForm
title="Login"
description="Enter your credentials to access your account."
icon="i-lucide-user"
:providers="providers"
:fields="fields"
separator="Providers"
class="max-w-md"
/>
</template>Separator 구성 요소의 속성을 전달하여 사용자 정의할 수 있습니다.
<script setup lang="ts">
import type { ButtonProps, AuthFormField } from '@nuxt/ui'
const providers = ref<ButtonProps[]>([
{
label: 'Google',
icon: 'i-simple-icons-google',
color: 'neutral',
variant: 'subtle'
},
{
label: 'GitHub',
icon: 'i-simple-icons-github',
color: 'neutral',
variant: 'subtle'
}
])
const fields = ref<AuthFormField[]>([
{
name: 'email',
type: 'text',
label: 'Email'
},
{
name: 'password',
type: 'password',
label: 'Password'
}
])
</script>
<template>
<UAuthForm
title="Login"
description="Enter your credentials to access your account."
icon="i-lucide-user"
:providers="providers"
:fields="fields"
:separator="{
icon: 'i-lucide-user'
}"
class="max-w-md"
/>
</template><script setup lang="ts">
import { ref } from 'vue'
import type { ButtonProps, AuthFormField } from '@nuxt/ui'
const providers = ref<ButtonProps[]>([
{
label: 'Google',
icon: 'i-simple-icons-google',
color: 'neutral',
variant: 'subtle'
},
{
label: 'GitHub',
icon: 'i-simple-icons-github',
color: 'neutral',
variant: 'subtle'
}
])
const fields = ref<AuthFormField[]>([
{
name: 'email',
type: 'text',
label: 'Email'
},
{
name: 'password',
type: 'password',
label: 'Password'
}
])
</script>
<template>
<UAuthForm
title="Login"
description="Enter your credentials to access your account."
icon="i-lucide-user"
:providers="providers"
:fields="fields"
:separator="{
icon: 'i-lucide-user'
}"
class="max-w-md"
/>
</template>Submit 제출
submit prop을 사용하여 양식의 제출 버튼을 변경합니다.
Button 구성 요소에서 variant, color, to 등의 속성을 전달할 수 있습니다.
<script setup lang="ts">
import type { AuthFormField } from '@nuxt/ui'
const fields = ref<AuthFormField[]>([
{
name: 'email',
type: 'text',
label: 'Email'
},
{
name: 'password',
type: 'password',
label: 'Password'
}
])
</script>
<template>
<UAuthForm
title="Login"
description="Enter your credentials to access your account."
icon="i-lucide-user"
:fields="fields"
:submit="{
label: 'Submit',
color: 'error',
variant: 'subtle'
}"
class="max-w-md"
/>
</template><script setup lang="ts">
import { ref } from 'vue'
import type { AuthFormField } from '@nuxt/ui'
const fields = ref<AuthFormField[]>([
{
name: 'email',
type: 'text',
label: 'Email'
},
{
name: 'password',
type: 'password',
label: 'Password'
}
])
</script>
<template>
<UAuthForm
title="Login"
description="Enter your credentials to access your account."
icon="i-lucide-user"
:fields="fields"
:submit="{
label: 'Submit',
color: 'error',
variant: 'subtle'
}"
class="max-w-md"
/>
</template>examples 예제
페이지 내에서
AuthForm 구성 요소를 PageCard 구성 요소로 래핑하여 login.vue 페이지 내에 표시할 수 있습니다.
<script setup lang="ts">
import * as z from 'zod'
import type { FormSubmitEvent, AuthFormField } from '@nuxt/ui'
const toast = useToast()
const fields: AuthFormField[] = [{
name: 'email',
type: 'email',
label: 'Email',
placeholder: 'Enter your email',
required: true
}, {
name: 'password',
label: 'Password',
type: 'password',
placeholder: 'Enter your password',
required: true
}, {
name: 'remember',
label: 'Remember me',
type: 'checkbox'
}]
const providers = [{
label: 'Google',
icon: 'i-simple-icons-google',
onClick: () => {
toast.add({ title: 'Google', description: 'Login with Google' })
}
}, {
label: 'GitHub',
icon: 'i-simple-icons-github',
onClick: () => {
toast.add({ title: 'GitHub', description: 'Login with GitHub' })
}
}]
const schema = z.object({
email: z.email('Invalid email'),
password: z.string('Password is required').min(8, 'Must be at least 8 characters')
})
type Schema = z.output<typeof schema>
function onSubmit(payload: FormSubmitEvent<Schema>) {
console.log('Submitted', payload)
}
</script>
<template>
<div class="flex flex-col items-center justify-center gap-4 p-4">
<UPageCard class="w-full max-w-md">
<UAuthForm
:schema="schema"
:fields="fields"
:providers="providers"
title="Welcome back!"
icon="i-lucide-lock"
@submit="onSubmit"
>
<template #description>
Don't have an account? <ULink to="#" class="text-primary font-medium">Sign up</ULink>.
</template>
<template #password-hint>
<ULink to="#" class="text-primary font-medium" tabindex="-1">Forgot password?</ULink>
</template>
<template #validation>
<UAlert color="error" icon="i-lucide-info" title="Error signing in" />
</template>
<template #footer>
By signing in, you agree to our <ULink to="#" class="text-primary font-medium">Terms of Service</ULink>.
</template>
</UAuthForm>
</UPageCard>
</div>
</template>
API
Props (### Props)
| Prop | Default | Type |
|---|---|---|
as | 'div' | anyThe element or component this component should render as. |
icon | anyThe icon displayed above the title. | |
title | string | |
description | string | |
fields | F[] | |
providers | ButtonProps[]Display a list of Button under the description.
| |
separator | 'or' | string | SeparatorPropsThe text displayed in the separator. |
submit | Omit<ButtonProps, LinkPropsKeys>Display a submit button at the bottom of the form.
| |
schema | T | |
validate | (state: Partial<InferInput<T>>): FormError<string>[] | Promise<FormError<string>[]> | |
validateOn | FormInputEvents[] | |
validateOnInputDelay | number | |
disabled | boolean | |
loading | boolean | |
loadingAuto | boolean | |
name | string | |
autocomplete | string | |
acceptcharset | string | |
action | string | |
enctype | string | |
method | string | |
novalidate | false | true | "true" | "false" | |
target | string | |
ui | { root?: SlotClass; header?: SlotClass; leading?: SlotClass; leadingIcon?: SlotClass; title?: SlotClass; description?: SlotClass; body?: SlotClass; providers?: SlotClass; checkbox?: SlotClass; select?: SlotClass; password?: SlotClass; otp?: SlotClass; input?: SlotClass; separator?: SlotClass; form?: SlotClass; footer?: SlotClass; } |
슬롯
| Slot | Type |
|---|---|
header | {} |
leading | { ui: object; } |
title | {} |
description | {} |
providers | {} |
separator | {} |
validation | {} |
submit | { loading: boolean; } |
footer | {} |
Emits
| Event | Type |
|---|---|
submit | [payload: FormSubmitEvent<InferOutput<T>>] |
exose 소개
useTemplateRef를 사용하여 형식화된 구성 요소 인스턴스(formRef 및 상태 노출)에 액세스할 수 있습니다. 예를 들어, 별도의 양식(예: "reset" 양식)에서 다음을 수행할 수 있습니다.
<script setup lang="ts">
const authForm = useTemplateRef('authForm')
</script>
<template>
<UAuthForm ref="authForm" />
</template>
이렇게 하면 다음과 같은 (노출) 속성에 액세스할 수 있습니다.This gives you access to the following (exposed) properties:
| 이름 (Name) | 유형 (Type) |
|---|---|
formRef | Ref<HTMLFormElement | null> (Ref<HTMLFormElement | null>) |
state 파일 | Reactive<FormStateType> |
Theme (## 테마)
export default defineAppConfig({
ui: {
authForm: {
slots: {
root: 'w-full space-y-6',
header: 'flex flex-col text-center',
leading: 'mb-2',
leadingIcon: 'size-8 shrink-0 inline-block',
title: 'text-xl text-pretty font-semibold text-highlighted',
description: 'mt-1 text-base text-pretty text-muted',
body: 'gap-y-6 flex flex-col',
providers: 'space-y-3',
checkbox: '',
select: 'w-full',
password: 'w-full',
otp: 'w-full',
input: 'w-full',
separator: '',
form: 'space-y-5',
footer: 'text-sm text-center text-muted mt-2'
}
}
}
})import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import ui from '@nuxt/ui/vite'
export default defineConfig({
plugins: [
vue(),
ui({
ui: {
authForm: {
slots: {
root: 'w-full space-y-6',
header: 'flex flex-col text-center',
leading: 'mb-2',
leadingIcon: 'size-8 shrink-0 inline-block',
title: 'text-xl text-pretty font-semibold text-highlighted',
description: 'mt-1 text-base text-pretty text-muted',
body: 'gap-y-6 flex flex-col',
providers: 'space-y-3',
checkbox: '',
select: 'w-full',
password: 'w-full',
otp: 'w-full',
input: 'w-full',
separator: '',
form: 'space-y-5',
footer: 'text-sm text-center text-muted mt-2'
}
}
}
})
]
})