ChatMessagePRO

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

用法

ChatMessage 组件将 <article> 元素渲染为 user 用户或 assistant 助手聊天消息。

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

内容

使用 content 属性显示消息内容。

你好!请告诉我更多关于使用 Nuxt UI Pro 构建 AI 聊天机器人的信息。
<template>
  <UChatMessage content="Hello! Tell me more about building AI chatbots with Nuxt UI Pro." />
</template>

方向

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

你好!请告诉我更多关于使用 Nuxt UI Pro 构建 AI 聊天机器人的信息。
<template>
  <UChatMessage
    side="right"
    content="Hello! Tell me more about building AI chatbots with Nuxt UI Pro."
  />
</template>
使用 ChatMessages 组件时,side 属性对于 assistant 消息设置为 left,对于 user 消息设置为 right

样式

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

你好!请告诉我更多关于使用 Nuxt UI Pro 构建 AI 聊天机器人的信息。
<template>
  <UChatMessage
    variant="soft"
    content="Hello! Tell me more about building AI chatbots with Nuxt UI Pro."
  />
</template>
使用 ChatMessages 组件时,variant 属性对于 assistant 消息设置为 naked,对于 user 消息设置为 soft

Icon

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

你好!请告诉我更多关于使用 Nuxt UI Pro 构建 AI 聊天机器人的信息。
<template>
  <UChatMessage
    icon="i-lucide-user"
    variant="soft"
    side="right"
    content="Hello! Tell me more about building AI chatbots with Nuxt UI Pro."
  />
</template>

Avatar

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

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

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

Nuxt UI Pro 提供了构建 AI 聊天机器人的多项功能,包括 ChatMessage、ChatMessages 和 ChatPrompt 组件。最佳实践包括使用 Vercel AI SDK 中的 useChat composable、使用变体实现适当的消息样式,以及利用内置操作进行消息交互。这些组件通过主题支持和响应式设计实现了完全可定制。
<template>
  <UChatMessage
    :avatar="{
      icon: 'i-lucide-bot'
    }"
    content="Nuxt UI Pro offers several features for building AI chatbots including the ChatMessage, ChatMessages, and ChatPrompt components. Best practices include using the useChat composable from Vercel AI SDK, 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 Pro 提供了构建 AI 聊天机器人的多项功能,包括 ChatMessage、ChatMessages 和 ChatPrompt 组件。最佳实践包括使用 Vercel AI SDK 中的 useChat composable、使用变体实现适当的消息样式,以及利用内置操作进行消息交互。这些组件通过主题支持和响应式设计实现了完全可定制。
<script setup lang="ts">
const actions = ref([
  {
    label: 'Copy to clipboard',
    icon: 'i-lucide-copy'
  }
])
</script>

<template>
  <UChatMessage
    :actions="actions"
    content="Nuxt UI Pro offers several features for building AI chatbots including the ChatMessage, ChatMessages, and ChatPrompt components. Best practices include using the useChat composable from Vercel AI SDK, 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

content

string

消息的文本内容。尽可能使用部分(parts)。

id

string

消息的唯一标识符。

role

"data" | "user" | "system" | "assistant"

'data' 角色已弃用。

icon

string

variant

'naked'

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

avatar

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

side

'left'

"right" | "left"

data

null | string | number | false | true | { [value: string]: JSONValue; } | JSONValue[]

用于数据消息。

actions

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

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

compact

false

boolean

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

createdAt

Date

消息的时间戳。

reasoning

string

消息的推理内容。

experimental_attachments

Attachment[]

与消息一起发送的附加附件。

annotations

JSONValue[]

通过 StreamData 在服务器端添加的额外消息特定信息

toolInvocations

ToolInvocation[]

助理作为此消息一部分所做的工具调用(可以是工具请求或工具结果,取决于调用是否已完成)。

parts

(TextUIPart | ReasoningUIPart | ToolInvocationUIPart | SourceUIPart | FileUIPart | StepStartUIPart)[]

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

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

ui

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

插槽

插槽类型
leading

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

content

{ content: string; }

actions

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

主题

app.config.ts
export default defineAppConfig({
  uiPro: {
    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',
        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({
      uiPro: {
        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',
            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 uiPro from '@nuxt/ui-pro/vite'

export default defineConfig({
  plugins: [
    vue(),
    uiPro({
      uiPro: {
        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',
            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'
          }
        }
      }
    })
  ]
})