ChatPrompt专业版

TextareaGitHub
一个增强型文本区域,用于在 AI 聊天界面中提交提示。

用法

ChatPrompt 组件会渲染一个 <form> 元素,并扩展了 Textarea 组件,以便您可以传入任何属性,例如 iconplaceholderautofocus 等。

ChatPrompt 处理以下事件
  • 当用户按下 键或点击提交按钮时,表单会被提交。
  • 键被按下时,文本区域会失去焦点,并发出一个 close 事件。

变体

使用 variant 属性来改变提示的样式。默认为 outline

<template>
  <UChatPrompt variant="soft" />
</template>

示例

这些聊天组件设计用于与 Vercel AI SDK 中的 useChat 可组合项一起使用。
查阅我们在 GitHub 上的 AI 聊天模板 源代码,以获取实际示例。

在页面内

将 ChatPrompt 组件与 useChat 组合式函数结合使用,以在页面中显示聊天提示。

传入 input 属性以及 error 属性,以在发生错误时禁用文本区域。

pages/[id].vue
<script setup lang="ts">
import { useChat } from '@ai-sdk/vue'

const { messages, input, handleSubmit, reload, stop, status, error } = useChat()
</script>

<template>
  <UDashboardPanel>
    <template #body>
      <UContainer>
        <UChatMessages :messages="messages" :status="status">
          <template #content="{ message }">
            <MDC :value="message.content" :cache-key="message.id" unwrap="p" />
          </template>
        </UChatMessages>
      </UContainer>
    </template>

    <template #footer>
      <UContainer>
        <UChatPrompt v-model="input" :error="error" @submit="handleSubmit">
          <UChatPromptSubmit :status="status" @stop="stop" @reload="reload" />
        </UChatPrompt>
      </UContainer>
    </template>
  </UDashboardPanel>
</template>

您也可以将其用作聊天界面的起点。

pages/index.vue
<script setup lang="ts">
const input = ref('')
const loading = ref(false)

async function onSubmit() {
  loading.value = true

  const chat = await $fetch('/api/chats', {
    method: 'POST',
    body: { input }
  })

  navigateTo(`/chat/${chat.id}`)
}
</script>

<template>
  <UDashboardPanel>
    <template #body>
      <UContainer>
        <h1>How can I help you today?</h1>

        <UChatPrompt v-model="input" :status="loading ? 'streaming' : 'ready'" @submit="onSubmit">
          <UChatPromptSubmit />
        </UChatPrompt>
      </UContainer>
    </template>
  </UDashboardPanel>
</template>

API

属性

属性默认值类型
as

'form'

any

此组件应渲染为的元素或组件。

placeholder

t('chatPrompt.placeholder')

string

这是文本区域的占位符文本。

autofocus

true

boolean

autoresize

true

boolean

rows

1

number

variant

'outline'

"outline" | "soft" | "subtle" | "naked"

error

错误

图标

string

根据 leadingtrailing 属性显示图标。

loading

boolean

当为 true 时,将显示加载图标。

loadingIcon

appConfig.ui.icons.loading

string

loading 属性为 true 时显示的图标。

avatar

AvatarProps

在左侧显示头像。

autofocusDelay

number

autoresizeDelay

number

maxrows

number

modelValue

string

ui

{ root?: ClassNameValue; header?: ClassNameValue; body?: ClassNameValue; footer?: ClassNameValue; base?: ClassNameValue; } & { root?: ClassNameValue; base?: ClassNameValue; leading?: ClassNameValue; leadingIcon?: ClassNameValue; leadingAvatar?: ClassNameValue; leadingAvatarSize?: ClassNameValue; trailing?: ClassNameValue; trailingIcon?: ClassNameValue; }

插槽

插槽类型
页头

{}

页脚

{}

前置

{}

default

{}

尾部

{}

事件

事件类型
close

[event: Event]

submit

[event: Event]

update:modelValue

[value: string]

主题

app.config.ts
export default defineAppConfig({
  uiPro: {
    chatPrompt: {
      slots: {
        root: 'relative flex flex-col items-stretch gap-2 px-2.5 py-2 w-full rounded-lg backdrop-blur',
        header: 'flex items-center gap-1.5',
        body: 'items-start',
        footer: 'flex items-center justify-between gap-1.5',
        base: 'text-base/5'
      },
      variants: {
        variant: {
          outline: {
            root: 'bg-default/75 ring ring-default'
          },
          soft: {
            root: 'bg-elevated/50'
          },
          subtle: {
            root: 'bg-elevated/50 ring ring-default'
          },
          naked: {
            root: ''
          }
        }
      },
      defaultVariants: {
        variant: 'outline'
      }
    }
  }
})
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: {
        chatPrompt: {
          slots: {
            root: 'relative flex flex-col items-stretch gap-2 px-2.5 py-2 w-full rounded-lg backdrop-blur',
            header: 'flex items-center gap-1.5',
            body: 'items-start',
            footer: 'flex items-center justify-between gap-1.5',
            base: 'text-base/5'
          },
          variants: {
            variant: {
              outline: {
                root: 'bg-default/75 ring ring-default'
              },
              soft: {
                root: 'bg-elevated/50'
              },
              subtle: {
                root: 'bg-elevated/50 ring ring-default'
              },
              naked: {
                root: ''
              }
            }
          },
          defaultVariants: {
            variant: 'outline'
          }
        }
      }
    })
  ]
})
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: {
        chatPrompt: {
          slots: {
            root: 'relative flex flex-col items-stretch gap-2 px-2.5 py-2 w-full rounded-lg backdrop-blur',
            header: 'flex items-center gap-1.5',
            body: 'items-start',
            footer: 'flex items-center justify-between gap-1.5',
            base: 'text-base/5'
          },
          variants: {
            variant: {
              outline: {
                root: 'bg-default/75 ring ring-default'
              },
              soft: {
                root: 'bg-elevated/50'
              },
              subtle: {
                root: 'bg-elevated/50 ring ring-default'
              },
              naked: {
                root: ''
              }
            }
          },
          defaultVariants: {
            variant: 'outline'
          }
        }
      }
    })
  ]
})