ChatReasoning 대화
Usage
ChatReasoning 구성 요소는 AI 추론 또는 사고 내용을 표시하는 축소 가능한 블록을 렌더링합니다. 스트리밍 중에는 자동으로 열리고 이후에는 자동으로 닫힙니다.
<script setup lang="ts">
const streaming = ref(false)
const text = ref('')
async function simulateStreaming() {
streaming.value = true
text.value = ''
const content =
'The user is asking about Vue components. I should explain the Composition API pattern and how it relates to their question about reactive state management. Let me think about the best way to structure this response.\n\nFirst, I need to consider the key differences between the Options API and Composition API. The Composition API was introduced in Vue 3 to address limitations of the Options API when building large-scale applications.\n\nFor reactive state management specifically, the Composition API offers ref() for primitive values and reactive() for objects.'
for (const char of content) {
text.value += char
await new Promise((resolve) => setTimeout(resolve, 10))
}
streaming.value = false
}
onMounted(simulateStreaming)
</script>
<template>
<UChatReasoning :text="text" :streaming="streaming" class="w-60" />
</template><script setup lang="ts">
import { ref, reactive, onMounted } from 'vue'
const streaming = ref(false)
const text = ref('')
async function simulateStreaming() {
streaming.value = true
text.value = ''
const content =
'The user is asking about Vue components. I should explain the Composition API pattern and how it relates to their question about reactive state management. Let me think about the best way to structure this response.\n\nFirst, I need to consider the key differences between the Options API and Composition API. The Composition API was introduced in Vue 3 to address limitations of the Options API when building large-scale applications.\n\nFor reactive state management specifically, the Composition API offers ref() for primitive values and reactive() for objects.'
for (const char of content) {
text.value += char
await new Promise((resolve) => setTimeout(resolve, 10))
}
streaming.value = false
}
onMounted(simulateStreaming)
</script>
<template>
<UChatReasoning :text="text" :streaming="streaming" class="w-60" />
</template>Text 파일
text 소품을 사용하여 추론 내용을 설정합니다. 텍스트는 축소 가능한 본문 안에 표시됩니다.
<template>
<UChatReasoning text="The user is asking about Vue components..." />
</template>스트리밍
streaming Prop을 사용하여 활성 추론을 나타냅니다. 구성 요소는 스트리밍이 시작되면 자동으로 열리고 종료되면 자동으로 닫힙니다.
<template>
<UChatReasoning streaming text="The user is asking about Vue components..." />
</template>@nuxt/ui/utils/ai의 isPartStreaming 유틸리티를 사용하여 부품이 현재 스트리밍되고 있는지 확인합니다.시머
스트리밍 시 트리거 레이블은 ChatShimmer 구성 요소를 사용합니다. shimmer Prop을 사용하여 duration 및 spread를 사용자 정의합니다.
<template>
<UChatReasoning
streaming
text="The user is asking about Vue components..."
:shimmer="{
duration: 2,
spread: 2
}"
/>
</template>Icon 이미지
icon 소품을 사용하여 트리거 옆에 Icon 구성 요소를 표시합니다.
<template>
<UChatReasoning icon="i-lucide-brain" text="The user is asking about Vue components..." />
</template>Chevron 차량 대여
chevron Prop을 사용하여 Chevron 아이콘의 위치를 변경합니다.
chevron가 icon로 설정되어 있으면 아이콘이 커서를 놓고 열려 있을 때 chevron과 스왑됩니다.<template>
<UChatReasoning
chevron="leading"
icon="i-lucide-brain"
text="The user is asking about Vue components..."
/>
</template>Chevron 아이콘 아이콘
chevron-icon 소품을 사용하여 chevron Icon 를 사용자 정의합니다. 기본값은 i-lucide-chevron-down입니다.
<template>
<UChatReasoning
chevron-icon="i-lucide-arrow-down"
text="The user is asking about Vue components..."
/>
</template>examples 예제
API
Props (### Props)
| Prop | Default | Type |
|---|---|---|
text | stringThe reasoning text content to display. | |
streaming | false | boolean Whether the reasoning content is currently streaming. |
duration | numberThe duration in seconds that the AI spent reasoning. If not provided, it will be calculated automatically based on streaming time. | |
icon | anyThe icon displayed next to the trigger. | |
chevron | 'trailing' | "leading" | "trailing"The position of the chevron icon. |
chevronIcon | appConfig.ui.icons.chevronDown | anyThe icon displayed as the chevron. |
autoCloseDelay | 500 | numberThe delay in milliseconds before auto-closing when streaming ends.
Set to |
shimmer | Partial<Omit<ChatShimmerProps, "text">>Customize the | |
disabled | boolean When | |
open | undefined | boolean The controlled open state of the collapsible. Can be binded with |
defaultOpen | boolean The open state of the collapsible when it is initially rendered. | |
unmountOnHide | false | boolean When |
ui | { root?: SlotClass; trigger?: SlotClass; leading?: SlotClass; leadingIcon?: SlotClass; chevronIcon?: SlotClass; label?: SlotClass; trailingIcon?: SlotClass; content?: SlotClass; body?: SlotClass; } |
슬롯
| Slot | Type |
|---|---|
default | { open: boolean; } |
Emits
| Event | Type |
|---|---|
update:open | [value: boolean] |
테마
export default defineAppConfig({
ui: {
chatReasoning: {
slots: {
root: '',
trigger: [
'group flex w-full items-center gap-1.5 text-muted text-sm disabled:cursor-default disabled:hover:text-muted hover:text-default rounded-sm outline-primary/25 focus-visible:outline-3 min-w-0',
'transition-colors'
],
leading: 'relative size-4 shrink-0',
leadingIcon: 'size-4 shrink-0',
chevronIcon: 'size-4 shrink-0 group-data-[state=open]:rotate-180 transition-transform duration-200 ease-out motion-reduce:transition-none',
label: 'truncate',
trailingIcon: 'size-4 shrink-0 group-data-[state=open]:rotate-180 transition-transform duration-200 ease-out motion-reduce:transition-none',
content: 'data-[state=open]:animate-[collapsible-down_200ms_var(--ease-out)] data-[state=closed]:animate-[collapsible-up_200ms_var(--ease-out)] data-[state=closed]:overflow-hidden rounded-sm outline-primary/25 has-focus-visible:outline-3',
body: 'max-h-[200px] pt-2 overflow-y-auto text-sm text-dimmed whitespace-pre-wrap focus:outline-none'
},
variants: {
chevron: {
leading: {
leadingIcon: 'group-hover:opacity-0'
},
trailing: ''
},
alone: {
false: {
leadingIcon: [
'absolute inset-0 group-data-[state=open]:opacity-0',
'transition-opacity duration-200 ease-out'
],
chevronIcon: [
'absolute inset-0 opacity-0 group-hover:opacity-100 group-data-[state=open]:opacity-100',
'transition-[rotate,opacity] duration-200 ease-out motion-reduce:transition-none'
]
}
}
}
}
}
})import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import ui from '@nuxt/ui/vite'
export default defineConfig({
plugins: [
vue(),
ui({
ui: {
chatReasoning: {
slots: {
root: '',
trigger: [
'group flex w-full items-center gap-1.5 text-muted text-sm disabled:cursor-default disabled:hover:text-muted hover:text-default rounded-sm outline-primary/25 focus-visible:outline-3 min-w-0',
'transition-colors'
],
leading: 'relative size-4 shrink-0',
leadingIcon: 'size-4 shrink-0',
chevronIcon: 'size-4 shrink-0 group-data-[state=open]:rotate-180 transition-transform duration-200 ease-out motion-reduce:transition-none',
label: 'truncate',
trailingIcon: 'size-4 shrink-0 group-data-[state=open]:rotate-180 transition-transform duration-200 ease-out motion-reduce:transition-none',
content: 'data-[state=open]:animate-[collapsible-down_200ms_var(--ease-out)] data-[state=closed]:animate-[collapsible-up_200ms_var(--ease-out)] data-[state=closed]:overflow-hidden rounded-sm outline-primary/25 has-focus-visible:outline-3',
body: 'max-h-[200px] pt-2 overflow-y-auto text-sm text-dimmed whitespace-pre-wrap focus:outline-none'
},
variants: {
chevron: {
leading: {
leadingIcon: 'group-hover:opacity-0'
},
trailing: ''
},
alone: {
false: {
leadingIcon: [
'absolute inset-0 group-data-[state=open]:opacity-0',
'transition-opacity duration-200 ease-out'
],
chevronIcon: [
'absolute inset-0 opacity-0 group-hover:opacity-100 group-data-[state=open]:opacity-100',
'transition-[rotate,opacity] duration-200 ease-out motion-reduce:transition-none'
]
}
}
}
}
}
})
]
})