ChatRedeneren
Gebruik
De ChatReasoning-component geeft een opvouwbaar blok weer dat AI-redenering of denkinhoud weergeeft. Het wordt automatisch geopend tijdens het streamen en wordt daarna automatisch gesloten.
<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>useScrollShadow-compositie om vervagende schaduwen toe te passen wanneer deze overlopen.Tekst
Gebruik de text prop om de redeneerinhoud in te stellen. De tekst wordt weergegeven in de opvouwbare behuizing.
<template>
<UChatReasoning text="The user is asking about Vue components..." />
</template>Streamen
Gebruik de streaming prop om actieve redenering aan te geven. Het onderdeel wordt automatisch geopend wanneer het streamen begint en wordt automatisch gesloten wanneer het eindigt.
<template>
<UChatReasoning streaming text="The user is asking about Vue components..." />
</template>isPartStreaming hulpprogramma van @nuxt/ui/utils/ai om te bepalen of een onderdeel momenteel wordt gestreamd.Shimmer
Bij het streamen gebruikt het triggerlabel de ChatShimmer component. Gebruik de shimmer prop om zijn duration en spread aan te passen.
<template>
<UChatReasoning
streaming
text="The user is asking about Vue components..."
:shimmer="{
duration: 2,
spread: 2
}"
/>
</template>Icoon
Gebruik de icon prop om een Icon naast de trigger weer te geven.
<template>
<UChatReasoning icon="i-lucide-brain" text="The user is asking about Vue components..." />
</template>Chevron
Gebruik de chevron prop om de positie van het chevron icoon te veranderen.
chevron is ingesteld op leading met een icon, wisselt het pictogram met de chevron bij zweven en openen.<template>
<UChatReasoning
chevron="leading"
icon="i-lucide-brain"
text="The user is asking about Vue components..."
/>
</template>Chevron pictogram
Gebruik de chevron-icon prop om de chevron Icon aan te passen. Standaard i-lucide-chevron-down.
<template>
<UChatReasoning
chevron-icon="i-lucide-arrow-down"
text="The user is asking about Vue components..."
/>
</template>Voorbeelden
API
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; } |
Slots
| Slot | Type |
|---|---|
default | { open: boolean; } |
Uitzendt
| Event | Type |
|---|---|
update:open | [value: boolean] |
Thema
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'
]
}
}
}
}
}
})
]
})