AuthFormPRO

一个可定制的表单组件,用于创建登录、注册或密码重置表单。

用法

基于 Form 组件构建,AuthForm 组件可以在你的页面中使用或包裹在 PageCard 中。

表单将根据 fields 属性自行构建,并且状态将在内部处理。你可以将传递给 FormFieldInput 的所有属性传递给每个字段。

登录
输入您的凭据访问您的账户。
<script setup lang="ts">
import * as z from 'zod'
import type { FormSubmitEvent } from '@nuxt/ui'

const toast = useToast()

const fields = [{
  name: 'email',
  type: 'text' as const,
  label: 'Email',
  placeholder: 'Enter your email',
  required: true
}, {
  name: 'password',
  label: 'Password',
  type: 'password' as const,
  placeholder: 'Enter your password'
}, {
  name: 'remember',
  label: 'Remember me',
  type: 'checkbox' as const
}]

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.string().email('Invalid email'),
  password: z.string().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>

标题

使用 title 属性设置表单的标题。

登录
<script setup lang="ts">
const fields = ref([
  {
    name: 'email',
    type: 'text',
    label: 'Email'
  },
  {
    name: 'password',
    type: 'password',
    label: 'Password'
  }
])
</script>

<template>
  <UAuthForm class="max-w-md" title="Login" :fields="fields" />
</template>

描述

使用 description 属性设置表单的描述。

登录
输入您的凭据访问您的账户。
<script setup lang="ts">
const fields = ref([
  {
    name: 'email',
    type: 'text',
    label: 'Email'
  },
  {
    name: 'password',
    type: 'password',
    label: 'Password'
  }
])
</script>

<template>
  <UAuthForm
    class="max-w-md"
    title="Login"
    description="Enter your credentials to access your account."
    :fields="fields"
  />
</template>

图标

使用 icon 属性设置表单的图标。

登录
输入您的凭据访问您的账户。
<script setup lang="ts">
const fields = ref([
  {
    name: 'email',
    type: 'text',
    label: 'Email'
  },
  {
    name: 'password',
    type: 'password',
    label: 'Password'
  }
])
</script>

<template>
  <UAuthForm
    class="max-w-md"
    title="Login"
    description="Enter your credentials to access your account."
    icon="i-lucide-user"
    :fields="fields"
  />
</template>

提供者

使用 providers 属性为表单添加提供者。

你可以传递 Button 组件的任何属性,例如 variantcolorto 等。

登录
输入您的凭据访问您的账户。
<script setup lang="ts">
const fields = ref([
  {
    name: 'email',
    type: 'text',
    label: 'Email'
  },
  {
    name: 'password',
    type: 'password',
    label: 'Password'
  }
])
const providers = ref([
  {
    label: 'Google',
    icon: 'i-simple-icons-google',
    color: 'neutral',
    variant: 'subtle'
  },
  {
    label: 'GitHub',
    icon: 'i-simple-icons-github',
    color: 'neutral',
    variant: 'subtle'
  }
])
</script>

<template>
  <UAuthForm
    class="max-w-md"
    title="Login"
    description="Enter your credentials to access your account."
    icon="i-lucide-user"
    :providers="providers"
    :fields="fields"
  />
</template>

分隔符

使用 separator 属性自定义提供者和字段之间的 Separator。默认为 or

登录
输入您的凭据访问您的账户。
<script setup lang="ts">
const providers = ref([
  {
    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([
  {
    name: 'email',
    type: 'text',
    label: 'Email'
  },
  {
    name: 'password',
    type: 'password',
    label: 'Password'
  }
])
</script>

<template>
  <UAuthForm
    class="max-w-md"
    title="Login"
    description="Enter your credentials to access your account."
    icon="i-lucide-user"
    :providers="providers"
    :fields="fields"
    separator="Providers"
  />
</template>

你可以传递 Separator 组件的任何属性来对其进行自定义。

登录
输入您的凭据访问您的账户。
<script setup lang="ts">
const providers = ref([
  {
    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([
  {
    name: 'email',
    type: 'text',
    label: 'Email'
  },
  {
    name: 'password',
    type: 'password',
    label: 'Password'
  }
])
</script>

<template>
  <UAuthForm
    class="max-w-md"
    title="Login"
    description="Enter your credentials to access your account."
    icon="i-lucide-user"
    :providers="providers"
    :fields="fields"
    :separator="{
      icon: 'i-lucide-user'
    }"
  />
</template>

提交

使用 submit 属性更改表单的提交按钮。

你可以传递 Button 组件的任何属性,例如 variantcolorto 等。

登录
输入您的凭据访问您的账户。
<script setup lang="ts">
const fields = ref([
  {
    name: 'email',
    type: 'text',
    label: 'Email'
  },
  {
    name: 'password',
    type: 'password',
    label: 'Password'
  }
])
</script>

<template>
  <UAuthForm
    class="max-w-md"
    title="Login"
    description="Enter your credentials to access your account."
    icon="i-lucide-user"
    :fields="fields"
    :submit="{
      label: 'Submit',
      color: 'error',
      variant: 'subtle'
    }"
  />
</template>

示例

在页面中使用

你可以使用 PageCard 组件包裹 AuthForm 组件,例如在 login.vue 页面中显示它。

欢迎回来!
没有账户?注册.
登录错误
通过登录,您同意我们的服务条款.
<script setup lang="ts">
import * as z from 'zod'
import type { FormSubmitEvent } from '@nuxt/ui'

const toast = useToast()

const fields = [{
  name: 'email',
  type: 'text' as const,
  label: 'Email',
  placeholder: 'Enter your email',
  required: true
}, {
  name: 'password',
  label: 'Password',
  type: 'password' as const,
  placeholder: 'Enter your password'
}, {
  name: 'remember',
  label: 'Remember me',
  type: 'checkbox' as const
}]

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.string().email('Invalid email'),
  password: z.string().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

'div'

any

该组件应渲染为何种元素或组件。

icon

string

显示在标题上方的图标。

title

string

description

string

fields

AuthFormField[]

providers

ButtonProps[]

在描述下方显示 Button 列表。 { color: 'neutral', variant: 'subtle', block: true }

separator

'or'

string | SeparatorProps

分隔符中显示的文本。

提交

ButtonProps

在表单底部显示一个提交按钮。 { label: 'Continue', block: true }

schema

Struct<any, any> | ObjectSchema<object, AnyObject, any, ""> | AnySchema<object> | ArraySchema<object> | AlternativesSchema<object> | BinarySchema<object> | BooleanSchema<object> | DateSchema<object> | FunctionSchema<object> | NumberSchema<object> | ObjectSchema<object> | StringSchema<object> | LinkSchema<object> | SymbolSchema<object> | StandardSchemaV1<object, object>

validate

(state: Partial<any>): FormError<string>[] | Promise<FormError<string>[]>

validateOn

FormInputEvents[]

validateOnInputDelay

number

disabled

boolean

loading

boolean

ui

{ root?: ClassNameValue; header?: ClassNameValue; leading?: ClassNameValue; leadingIcon?: ClassNameValue; title?: ClassNameValue; ... 5 more ...; footer?: ClassNameValue; }

插槽

插槽类型
header

{}

leading

{}

title

{}

description

{}

validation

{}

footer

{}

事件

事件类型
提交

FormSubmitEvent<any>

主题

app.config.ts
export default defineAppConfig({
  uiPro: {
    authForm: {
      slots: {
        root: 'w-full space-y-6',
        header: 'flex flex-col text-center',
        leading: 'mb-2',
        leadingIcon: 'size-8 shrink-0',
        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',
        separator: '',
        form: 'space-y-5',
        footer: 'text-sm text-center text-muted mt-2'
      }
    }
  }
})
vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import ui from '@nuxt/ui/vite'

export default defineConfig({
  plugins: [
    vue(),
    ui({
      uiPro: {
        authForm: {
          slots: {
            root: 'w-full space-y-6',
            header: 'flex flex-col text-center',
            leading: 'mb-2',
            leadingIcon: 'size-8 shrink-0',
            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',
            separator: '',
            form: 'space-y-5',
            footer: 'text-sm text-center text-muted mt-2'
          }
        }
      }
    })
  ]
})
vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import uiPro from '@nuxt/ui-pro/vite'

export default defineConfig({
  plugins: [
    vue(),
    uiPro({
      uiPro: {
        authForm: {
          slots: {
            root: 'w-full space-y-6',
            header: 'flex flex-col text-center',
            leading: 'mb-2',
            leadingIcon: 'size-8 shrink-0',
            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',
            separator: '',
            form: 'space-y-5',
            footer: 'text-sm text-center text-muted mt-2'
          }
        }
      }
    })
  ]
})