聊天消息

GitHub
显示带有图标、头像和操作的聊天消息。

用法

ChatMessage 组件为 userassistant 聊天消息渲染一个 <article> 元素。

你好!告诉我更多关于使用 Nuxt UI 构建 AI 聊天机器人的信息。
使用 ChatMessages 组件来显示聊天消息列表。

部分

使用 parts 属性以 AI SDK v5 格式显示消息内容。

你好!告诉我更多关于使用 Nuxt UI 构建 AI 聊天机器人的信息。
<template>
  <UChatMessage
    :parts="[
      {
        type: 'text',
        text: 'Hello! Tell me more about building AI chatbots with Nuxt UI.'
      }
    ]"
  />
</template>
parts 属性是 AI SDK v5 的推荐格式。每个部分都有一个 type(例如,“text”)和相应的内容。ChatMessage 组件还支持已弃用的 content 属性以实现向后兼容性。

方向

使用 side 属性在左侧或右侧显示消息。

你好!告诉我更多关于使用 Nuxt UI 构建 AI 聊天机器人的信息。
<template>
  <UChatMessage
    side="right"
    :parts="[
      {
        type: 'text',
        text: 'Hello! Tell me more about building AI chatbots with Nuxt UI.'
      }
    ]"
  />
</template>
使用 ChatMessages 组件时,assistant 消息的 side 属性设置为 leftuser 消息的 right

变体

使用 variant 属性更改消息样式。

你好!告诉我更多关于使用 Nuxt UI 构建 AI 聊天机器人的信息。
<template>
  <UChatMessage
    variant="soft"
    :parts="[
      {
        type: 'text',
        text: 'Hello! Tell me more about building AI chatbots with Nuxt UI.'
      }
    ]"
  />
</template>
使用 ChatMessages 组件时,assistant 消息的 variant 属性设置为 nakeduser 消息的 soft

Icon

使用 icon 属性在消息旁边显示 Icon 组件。

你好!告诉我更多关于使用 Nuxt UI 构建 AI 聊天机器人的信息。
<template>
  <UChatMessage
    icon="i-lucide-user"
    variant="soft"
    side="right"
    :parts="[
      {
        type: 'text',
        text: 'Hello! Tell me more about building AI chatbots with Nuxt UI.'
      }
    ]"
  />
</template>

Avatar

使用 avatar 属性在消息旁边显示 Avatar 组件。

你好!告诉我更多关于使用 Nuxt UI 构建 AI 聊天机器人的信息。
<template>
  <UChatMessage
    :avatar="{
      src: 'https://github.com/benjamincanac.png'
    }"
    variant="soft"
    side="right"
    :parts="[
      {
        type: 'text',
        text: 'Hello! Tell me more about building AI chatbots with Nuxt UI.'
      }
    ]"
  />
</template>

您还可以使用 avatar.icon 属性将图标显示为头像。

Nuxt UI 提供了多种构建 AI 聊天机器人的功能,包括 ChatMessage、ChatMessages 和 ChatPrompt 组件。最佳实践包括使用 AI SDK v5 中的 Chat 类、通过变体实现适当的消息样式以及利用内置操作进行消息交互。这些组件完全可自定义,支持主题和响应式设计。
<template>
  <UChatMessage
    :avatar="{
      icon: 'i-lucide-bot'
    }"
    :parts="[
      {
        type: 'text',
        text: 'Nuxt UI offers several features for building AI chatbots including the ChatMessage, ChatMessages, and ChatPrompt components. Best practices include using the Chat class from AI SDK v5, implementing proper message styling with variants, and utilizing the built-in actions for message interactions. The components are fully customizable with theming support and responsive design.'
      }
    ]"
  />
</template>

操作

使用 actions 属性在消息下方显示操作,这些操作将在鼠标悬停在消息上时显示。

Nuxt UI 提供了多种构建 AI 聊天机器人的功能,包括 ChatMessage、ChatMessages 和 ChatPrompt 组件。最佳实践包括使用 AI SDK v5 中的 Chat 类、通过变体实现适当的消息样式以及利用内置操作进行消息交互。这些组件完全可自定义,支持主题和响应式设计。
<script setup lang="ts">
const actions = ref([
  {
    label: 'Copy to clipboard',
    icon: 'i-lucide-copy'
  }
])
</script>

<template>
  <UChatMessage
    :actions="actions"
    :parts="[
      {
        type: 'text',
        text: 'Nuxt UI offers several features for building AI chatbots including the ChatMessage, ChatMessages, and ChatPrompt components. Best practices include using the Chat class from AI SDK v5, implementing proper message styling with variants, and utilizing the built-in actions for message interactions. The components are fully customizable with theming support and responsive design.'
      }
    ]"
  />
</template>

API

属性

属性默认值类型
as

'article'

any

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

id

string

消息的唯一标识符。

role

"user" | "system" | "assistant"

消息的角色。

parts

UIMessagePart<UIDataTypes, UITools>[]

消息的部分。用于在 UI 中渲染消息。

应避免系统消息(而是将系统提示设置在服务器上)。它们可以包含文本部分。

用户消息可以包含文本部分和文件部分。

助手消息可以包含文本、推理、工具调用和文件部分。

图标

字符串 | 对象

avatar

AvatarProps & { [key: string]: any; }

variant

'naked'

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

side

'left'

"left" | "right"

actions

(Omit<ButtonProps, "onClick> & { onClick?: ((e: MouseEvent, message: UIMessage<unknown, UIDataTypes, UITools>) => void) | undefined; })[]

在消息下方显示操作列表。 label 将用于工具提示。 { size: 'xs', color: 'neutral', variant: 'ghost' }

紧凑

false

boolean

以紧凑样式渲染消息。在 UChatPalette 中使用时会自动完成。

内容

string

元数据

未知

消息的元数据。

ui

{ root?: ClassNameValue; container?: ClassNameValue; leading?: ClassNameValue; leadingIcon?: ClassNameValue; leadingAvatar?: ClassNameValue; leadingAvatarSize?: ClassNameValue; content?: ClassNameValue; actions?: ClassNameValue; }

插槽

插槽类型
前置

{ avatar: (AvatarProps & { [key: string]: any; }) | undefined; }

内容

ChatMessageProps

actions

{ actions: (Omit<ButtonProps, "onClick> & { onClick?: ((e: MouseEvent, message: UIMessage<unknown, UIDataTypes, UITools>) => void) | undefined; })[] | undefined; }

主题

app.config.ts
export default defineAppConfig({
  ui: {
    chatMessage: {
      slots: {
        root: 'group/message relative w-full',
        container: 'relative flex items-start group-data-[role=user]/message:max-w-[75%]',
        leading: 'inline-flex items-center justify-center min-h-6',
        leadingIcon: 'shrink-0',
        leadingAvatar: 'shrink-0',
        leadingAvatarSize: '',
        content: 'relative text-pretty min-w-0',
        actions: [
          'opacity-0 group-hover/message:opacity-100 absolute bottom-0 flex items-center',
          'transition-opacity'
        ]
      },
      variants: {
        variant: {
          solid: {
            content: 'bg-inverted text-inverted'
          },
          outline: {
            content: 'bg-default ring ring-default'
          },
          soft: {
            content: 'bg-elevated/50'
          },
          subtle: {
            content: 'bg-elevated/50 ring ring-default'
          },
          naked: {
            content: ''
          }
        },
        side: {
          left: {
            container: 'rtl:justify-end'
          },
          right: {
            container: 'ltr:justify-end ms-auto'
          }
        },
        leading: {
          true: ''
        },
        actions: {
          true: ''
        },
        compact: {
          true: {
            root: 'scroll-mt-3',
            container: 'gap-1.5 pb-3',
            leadingIcon: 'size-5',
            leadingAvatarSize: '2xs'
          },
          false: {
            root: 'scroll-mt-4 sm:scroll-mt-6',
            container: 'gap-3 pb-8',
            leadingIcon: 'size-8',
            leadingAvatarSize: 'md'
          }
        }
      },
      compoundVariants: [
        {
          compact: true,
          actions: true,
          class: {
            container: 'pb-8'
          }
        },
        {
          leading: true,
          compact: false,
          side: 'left',
          class: {
            actions: 'left-11'
          }
        },
        {
          leading: true,
          compact: true,
          side: 'left',
          class: {
            actions: 'left-6.5'
          }
        },
        {
          variant: [
            'solid',
            'outline',
            'soft',
            'subtle'
          ],
          compact: false,
          class: {
            content: 'px-4 py-3 rounded-lg min-h-12',
            leading: 'mt-2'
          }
        },
        {
          variant: [
            'solid',
            'outline',
            'soft',
            'subtle'
          ],
          compact: true,
          class: {
            content: 'px-2 py-1 rounded-lg min-h-8',
            leading: 'mt-1'
          }
        }
      ],
      defaultVariants: {
        variant: 'naked'
      }
    }
  }
})
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({
      ui: {
        chatMessage: {
          slots: {
            root: 'group/message relative w-full',
            container: 'relative flex items-start group-data-[role=user]/message:max-w-[75%]',
            leading: 'inline-flex items-center justify-center min-h-6',
            leadingIcon: 'shrink-0',
            leadingAvatar: 'shrink-0',
            leadingAvatarSize: '',
            content: 'relative text-pretty min-w-0',
            actions: [
              'opacity-0 group-hover/message:opacity-100 absolute bottom-0 flex items-center',
              'transition-opacity'
            ]
          },
          variants: {
            variant: {
              solid: {
                content: 'bg-inverted text-inverted'
              },
              outline: {
                content: 'bg-default ring ring-default'
              },
              soft: {
                content: 'bg-elevated/50'
              },
              subtle: {
                content: 'bg-elevated/50 ring ring-default'
              },
              naked: {
                content: ''
              }
            },
            side: {
              left: {
                container: 'rtl:justify-end'
              },
              right: {
                container: 'ltr:justify-end ms-auto'
              }
            },
            leading: {
              true: ''
            },
            actions: {
              true: ''
            },
            compact: {
              true: {
                root: 'scroll-mt-3',
                container: 'gap-1.5 pb-3',
                leadingIcon: 'size-5',
                leadingAvatarSize: '2xs'
              },
              false: {
                root: 'scroll-mt-4 sm:scroll-mt-6',
                container: 'gap-3 pb-8',
                leadingIcon: 'size-8',
                leadingAvatarSize: 'md'
              }
            }
          },
          compoundVariants: [
            {
              compact: true,
              actions: true,
              class: {
                container: 'pb-8'
              }
            },
            {
              leading: true,
              compact: false,
              side: 'left',
              class: {
                actions: 'left-11'
              }
            },
            {
              leading: true,
              compact: true,
              side: 'left',
              class: {
                actions: 'left-6.5'
              }
            },
            {
              variant: [
                'solid',
                'outline',
                'soft',
                'subtle'
              ],
              compact: false,
              class: {
                content: 'px-4 py-3 rounded-lg min-h-12',
                leading: 'mt-2'
              }
            },
            {
              variant: [
                'solid',
                'outline',
                'soft',
                'subtle'
              ],
              compact: true,
              class: {
                content: 'px-2 py-1 rounded-lg min-h-8',
                leading: 'mt-1'
              }
            }
          ],
          defaultVariants: {
            variant: 'naked'
          }
        }
      }
    })
  ]
})

更新日志

61b60— 功能:允许传递组件而不是名称 (#4766)

de782— feat!: 升级 ai-sdk 到 v5 (#4698)

5cb65— 特性:导入 @nuxt/ui-pro 组件