用法
AuthForm
组件基于 Form 组件构建,可以在你的页面中使用或封装在 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
属性构建自身,状态将在内部处理。
使用 fields
属性作为具有以下属性的对象数组
name?: string
type?: 'text' | 'password' | 'email' | 'number' | 'checkbox' | 'select' | 'otp'
每个字段必须包含一个 type
属性,它决定了输入组件和任何应用的附加属性:checkbox
字段使用 Checkbox 属性,select
字段使用 SelectMenu 属性,otp
字段使用 PinInput 属性,所有其他类型使用 Input 属性。
您还可以将 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>
标题
使用 title
属性设置表单的标题。
<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>
描述
使用 description
属性设置表单的描述。
<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>
Icon
使用 icon
属性设置表单的图标。
<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>
提供者
使用 providers
属性向表单添加提供者。
您可以传递 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>
Separator
使用 separator
属性自定义提供者和字段之间的 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>
您可以传递 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>
提交
使用 submit
属性更改表单的提交按钮。
您可以传递 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>
示例
在页面内
您可以将 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
属性
属性 | 默认值 | 类型 |
---|---|---|
as |
|
此组件应渲染为的元素或组件。 |
图标 |
显示在标题上方的图标。 | |
title |
| |
description |
| |
fields |
| |
providers |
在描述下方显示一个按钮列表。
| |
分隔符 |
|
分隔符中显示的文本。
|
submit |
在表单底部显示提交按钮。
| |
schema |
| |
validate |
| |
validateOn |
| |
validateOnInputDelay |
| |
disabled |
| |
loading |
| |
loadingAuto |
| |
ui |
|
插槽
插槽 | 类型 |
---|---|
页头 |
|
前置 |
|
title |
|
description |
|
providers |
|
validation |
|
submit |
|
页脚 |
|
事件
事件 | 类型 |
---|---|
submit |
|
可访问属性
您可以使用以下方式访问类型化的组件实例(暴露 formRef 和 state)useTemplateRef
。例如,在单独的表单(例如“重置”表单)中,您可以执行
<script setup lang="ts">
const authForm = useTemplateRef('authForm')
</script>
<template>
<UAuthForm ref="authForm" />
</template>
这使您可以访问以下(暴露的)属性
名称 | 类型 |
---|---|
formRef | Ref<HTMLFormElement | null> |
state | Reactive<FormStateType> |
主题
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'
}
}
}
})
]
})