ChatBerichten

GitHub
Geef een lijst met chatberichten weer, ontworpen om naadloos samen te werken met Vercel AI SDK.

Gebruik

Het ChatMessages-onderdeel geeft een lijst met ChatMessage componenten weer met behulp van de standaardsleuf of de messages-prop.

<template>
  <UChatMessages>
    <UChatMessage
      v-for="(message, index) in messages"
      :key="index"
      v-bind="message"
    />
  </UChatMessages>
</template>
Dit onderdeel is speciaal gebouwd voor AI-chatbots met functies zoals:
  • Eerste scroll naar beneden bij het laden (shouldScrollToBottom).
  • Continu naar beneden scrollen als er nieuwe berichten binnenkomen (shouldAutoScroll).
  • Een knop "Auto scroll" verschijnt wanneer omhoog wordt gescrold, zodat gebruikers terug kunnen springen naar de nieuwste berichten (autoScroll).
  • A laadindicator wordt weergegeven terwijl de assistent wordt verwerkt (status).
  • Ingezonden berichten worden naar de bovenkant van de viewport gescrold en de hoogte van het laatste gebruikersbericht wordt dynamisch aangepast.

Berichten

Gebruik de messages prop om een lijst met chatberichten weer te geven.

Hello, how are you?
I am doing well, thank you for asking! How can I assist you today?
What is the current weather in Tokyo?
Based on the latest data, Tokyo is currently experiencing sunny weather with temperatures around 24°C (75°F). It's a beautiful day with clear skies.
<script setup lang="ts">
const messages = ref([
  {
    id: '6045235a-a435-46b8-989d-2df38ca2eb47',
    role: 'user',
    parts: [
      {
        type: 'text',
        text: 'Hello, how are you?'
      }
    ]
  },
  {
    id: '7a92b3c1-d5f8-4e76-b8a9-3c1e5fb2e0d8',
    role: 'assistant',
    parts: [
      {
        type: 'text',
        text: 'I am doing well, thank you for asking! How can I assist you today?'
      }
    ]
  },
  {
    id: '9c84d6a7-8b23-4f12-a1d5-e7f3b9c05e2a',
    role: 'user',
    parts: [
      {
        type: 'text',
        text: 'What is the current weather in Tokyo?'
      }
    ]
  },
  {
    id: 'b2e5f8c3-a1d9-4e67-b3f2-c9d8e7a6b5f4',
    role: 'assistant',
    parts: [
      {
        type: 'text',
        text: "Based on the latest data, Tokyo is currently experiencing sunny weather with temperatures around 24°C (75°F). It's a beautiful day with clear skies."
      }
    ]
  }
])
</script>

<template>
  <UChatMessages :messages="messages" />
</template>
<script setup lang="ts">
import { ref } from 'vue'

const messages = ref([
  {
    id: '6045235a-a435-46b8-989d-2df38ca2eb47',
    role: 'user',
    parts: [
      {
        type: 'text',
        text: 'Hello, how are you?'
      }
    ]
  },
  {
    id: '7a92b3c1-d5f8-4e76-b8a9-3c1e5fb2e0d8',
    role: 'assistant',
    parts: [
      {
        type: 'text',
        text: 'I am doing well, thank you for asking! How can I assist you today?'
      }
    ]
  },
  {
    id: '9c84d6a7-8b23-4f12-a1d5-e7f3b9c05e2a',
    role: 'user',
    parts: [
      {
        type: 'text',
        text: 'What is the current weather in Tokyo?'
      }
    ]
  },
  {
    id: 'b2e5f8c3-a1d9-4e67-b3f2-c9d8e7a6b5f4',
    role: 'assistant',
    parts: [
      {
        type: 'text',
        text: "Based on the latest data, Tokyo is currently experiencing sunny weather with temperatures around 24°C (75°F). It's a beautiful day with clear skies."
      }
    ]
  }
])
</script>

<template>
  <UChatMessages :messages="messages" />
</template>

Status

Gebruik de status prop om een visuele indicator weer te geven wanneer de assistent aan het verwerken is.

Hello, how are you?
<script setup lang="ts">
const messages = ref([
  {
    id: '6045235a-a435-46b8-989d-2df38ca2eb47',
    role: 'user',
    parts: [
      {
        type: 'text',
        text: 'Hello, how are you?'
      }
    ]
  }
])
</script>

<template>
  <UChatMessages status="submitted" :messages="messages" />
</template>
<script setup lang="ts">
import { ref } from 'vue'

const messages = ref([
  {
    id: '6045235a-a435-46b8-989d-2df38ca2eb47',
    role: 'user',
    parts: [
      {
        type: 'text',
        text: 'Hello, how are you?'
      }
    ]
  }
])
</script>

<template>
  <UChatMessages status="submitted" :messages="messages" />
</template>
Hier is het detail van de verschillende statussen van de AI SDK useChat composable:
  • submitted: Het bericht is verzonden naar de API en we wachten op het begin van de responsstroom.
  • streaming: Het antwoord wordt actief gestreamd vanuit de API en ontvangt stukjes gegevens.
  • ready: De volledige reactie is ontvangen en verwerkt; er kan een nieuw gebruikersbericht worden verzonden.
  • error: Er is een fout opgetreden tijdens het API-verzoek, waardoor succesvolle voltooiing werd voorkomen.

Gebruiker

Gebruik de user prop om de ChatMessage rekwisieten voor user-berichten te wijzigen. Standaard:

  • side: 'right'
  • variant: 'soft'
Hello, how are you?
I am doing well, thank you for asking! How can I assist you today?
What is the current weather in Tokyo?
Based on the latest data, Tokyo is currently experiencing sunny weather with temperatures around 24°C (75°F). It's a beautiful day with clear skies.
<script setup lang="ts">
const messages = ref([
  {
    id: '6045235a-a435-46b8-989d-2df38ca2eb47',
    role: 'user',
    parts: [
      {
        type: 'text',
        text: 'Hello, how are you?'
      }
    ]
  },
  {
    id: '7a92b3c1-d5f8-4e76-b8a9-3c1e5fb2e0d8',
    role: 'assistant',
    parts: [
      {
        type: 'text',
        text: 'I am doing well, thank you for asking! How can I assist you today?'
      }
    ]
  },
  {
    id: '9c84d6a7-8b23-4f12-a1d5-e7f3b9c05e2a',
    role: 'user',
    parts: [
      {
        type: 'text',
        text: 'What is the current weather in Tokyo?'
      }
    ]
  },
  {
    id: 'b2e5f8c3-a1d9-4e67-b3f2-c9d8e7a6b5f4',
    role: 'assistant',
    parts: [
      {
        type: 'text',
        text: "Based on the latest data, Tokyo is currently experiencing sunny weather with temperatures around 24°C (75°F). It's a beautiful day with clear skies."
      }
    ]
  }
])
</script>

<template>
  <UChatMessages
    :user="{
      side: 'left',
      variant: 'solid',
      avatar: {
        src: 'https://github.com/benjamincanac.png',
        loading: 'lazy'
      }
    }"
    :messages="messages"
  />
</template>
<script setup lang="ts">
import { ref } from 'vue'

const messages = ref([
  {
    id: '6045235a-a435-46b8-989d-2df38ca2eb47',
    role: 'user',
    parts: [
      {
        type: 'text',
        text: 'Hello, how are you?'
      }
    ]
  },
  {
    id: '7a92b3c1-d5f8-4e76-b8a9-3c1e5fb2e0d8',
    role: 'assistant',
    parts: [
      {
        type: 'text',
        text: 'I am doing well, thank you for asking! How can I assist you today?'
      }
    ]
  },
  {
    id: '9c84d6a7-8b23-4f12-a1d5-e7f3b9c05e2a',
    role: 'user',
    parts: [
      {
        type: 'text',
        text: 'What is the current weather in Tokyo?'
      }
    ]
  },
  {
    id: 'b2e5f8c3-a1d9-4e67-b3f2-c9d8e7a6b5f4',
    role: 'assistant',
    parts: [
      {
        type: 'text',
        text: "Based on the latest data, Tokyo is currently experiencing sunny weather with temperatures around 24°C (75°F). It's a beautiful day with clear skies."
      }
    ]
  }
])
</script>

<template>
  <UChatMessages
    :user="{
      side: 'left',
      variant: 'solid',
      avatar: {
        src: 'https://github.com/benjamincanac.png',
        loading: 'lazy'
      }
    }"
    :messages="messages"
  />
</template>

Assistent

Gebruik de assistant-prop om de ChatMessage voor assistant-berichten te wijzigen. Standaard:

  • side: 'left'
  • variant: 'naked'
Hello, how are you?
I am doing well, thank you for asking! How can I assist you today?
What is the current weather in Tokyo?
Based on the latest data, Tokyo is currently experiencing sunny weather with temperatures around 24°C (75°F). It's a beautiful day with clear skies.
<script setup lang="ts">
const messages = ref([
  {
    id: '6045235a-a435-46b8-989d-2df38ca2eb47',
    role: 'user',
    parts: [
      {
        type: 'text',
        text: 'Hello, how are you?'
      }
    ]
  },
  {
    id: '7a92b3c1-d5f8-4e76-b8a9-3c1e5fb2e0d8',
    role: 'assistant',
    parts: [
      {
        type: 'text',
        text: 'I am doing well, thank you for asking! How can I assist you today?'
      }
    ]
  },
  {
    id: '9c84d6a7-8b23-4f12-a1d5-e7f3b9c05e2a',
    role: 'user',
    parts: [
      {
        type: 'text',
        text: 'What is the current weather in Tokyo?'
      }
    ]
  },
  {
    id: 'b2e5f8c3-a1d9-4e67-b3f2-c9d8e7a6b5f4',
    role: 'assistant',
    parts: [
      {
        type: 'text',
        text: "Based on the latest data, Tokyo is currently experiencing sunny weather with temperatures around 24°C (75°F). It's a beautiful day with clear skies."
      }
    ]
  }
])
</script>

<template>
  <UChatMessages
    :assistant="{
      side: 'left',
      variant: 'outline',
      avatar: {
        icon: 'i-lucide-bot'
      },
      actions: [
        {
          label: 'Copy to clipboard',
          icon: 'i-lucide-copy'
        }
      ]
    }"
    :messages="messages"
  />
</template>
<script setup lang="ts">
import { ref } from 'vue'

const messages = ref([
  {
    id: '6045235a-a435-46b8-989d-2df38ca2eb47',
    role: 'user',
    parts: [
      {
        type: 'text',
        text: 'Hello, how are you?'
      }
    ]
  },
  {
    id: '7a92b3c1-d5f8-4e76-b8a9-3c1e5fb2e0d8',
    role: 'assistant',
    parts: [
      {
        type: 'text',
        text: 'I am doing well, thank you for asking! How can I assist you today?'
      }
    ]
  },
  {
    id: '9c84d6a7-8b23-4f12-a1d5-e7f3b9c05e2a',
    role: 'user',
    parts: [
      {
        type: 'text',
        text: 'What is the current weather in Tokyo?'
      }
    ]
  },
  {
    id: 'b2e5f8c3-a1d9-4e67-b3f2-c9d8e7a6b5f4',
    role: 'assistant',
    parts: [
      {
        type: 'text',
        text: "Based on the latest data, Tokyo is currently experiencing sunny weather with temperatures around 24°C (75°F). It's a beautiful day with clear skies."
      }
    ]
  }
])
</script>

<template>
  <UChatMessages
    :assistant="{
      side: 'left',
      variant: 'outline',
      avatar: {
        icon: 'i-lucide-bot'
      },
      actions: [
        {
          label: 'Copy to clipboard',
          icon: 'i-lucide-copy'
        }
      ]
    }"
    :messages="messages"
  />
</template>

Automatisch scrollen

Gebruik de auto-scroll prop om de automatische scrollknop (met false-waarde) die wordt weergegeven bij het scrollen naar de bovenkant van de chat aan te passen of te verbergen. Standaard:

  • color: 'neutral'
  • variant: 'outline'

U kunt elke eigenschap van de Button component doorgeven om deze aan te passen.

Hello, how are you?
I am doing well, thank you for asking! How can I assist you today?
What is the current weather in Tokyo?
Based on the latest data, Tokyo is currently experiencing sunny weather with temperatures around 24°C (75°F). It's a beautiful day with clear skies. The forecast for the rest of the week shows a slight chance of rain on Thursday, with temperatures gradually rising to 28°C by the weekend. Humidity levels are moderate at around 65%, and wind speeds are light at 8 km/h from the southeast. Air quality is good with an index of 42. The UV index is high at 7, so it's recommended to wear sunscreen if you're planning to spend time outdoors. Sunrise was at 5:24 AM and sunset will be at 6:48 PM, giving Tokyo approximately 13 hours and 24 minutes of daylight today. The moon is currently in its waxing gibbous phase.
Can you recommend some popular tourist attractions in Kyoto?
Kyoto is known for its beautiful temples, traditional tea houses, and gardens. Some popular attractions include Kinkaku-ji (Golden Pavilion) with its stunning gold leaf exterior reflecting in the mirror pond, Fushimi Inari Shrine with its thousands of vermilion torii gates winding up the mountainside, Arashiyama Bamboo Grove where towering stalks create an otherworldly atmosphere, Kiyomizu-dera Temple perched on a hillside offering panoramic views of the city, and the historic Gion district where you might spot geisha hurrying to evening appointments through narrow stone-paved streets lined with traditional wooden machiya houses.
<script setup lang="ts">
const messages = ref([
  {
    id: '6045235a-a435-46b8-989d-2df38ca2eb47',
    role: 'user',
    parts: [
      {
        type: 'text',
        text: 'Hello, how are you?'
      }
    ]
  },
  {
    id: '7a92b3c1-d5f8-4e76-b8a9-3c1e5fb2e0d8',
    role: 'assistant',
    parts: [
      {
        type: 'text',
        text: 'I am doing well, thank you for asking! How can I assist you today?'
      }
    ]
  },
  {
    id: '9c84d6a7-8b23-4f12-a1d5-e7f3b9c05e2a',
    role: 'user',
    parts: [
      {
        type: 'text',
        text: 'What is the current weather in Tokyo?'
      }
    ]
  },
  {
    id: 'b2e5f8c3-a1d9-4e67-b3f2-c9d8e7a6b5f4',
    role: 'assistant',
    parts: [
      {
        type: 'text',
        text: "Based on the latest data, Tokyo is currently experiencing sunny weather with temperatures around 24°C (75°F). It's a beautiful day with clear skies. The forecast for the rest of the week shows a slight chance of rain on Thursday, with temperatures gradually rising to 28°C by the weekend. Humidity levels are moderate at around 65%, and wind speeds are light at 8 km/h from the southeast. Air quality is good with an index of 42. The UV index is high at 7, so it's recommended to wear sunscreen if you're planning to spend time outdoors. Sunrise was at 5:24 AM and sunset will be at 6:48 PM, giving Tokyo approximately 13 hours and 24 minutes of daylight today. The moon is currently in its waxing gibbous phase."
      }
    ]
  },
  {
    id: 'c3e5f8c3-a1d9-4e67-b3f2-c9d8e7a6b5f4',
    role: 'user',
    parts: [
      {
        type: 'text',
        text: 'Can you recommend some popular tourist attractions in Kyoto?'
      }
    ]
  },
  {
    id: 'd4f5g8c3-a1d9-4e67-b3f2-c9d8e7a6b5f4',
    role: 'assistant',
    parts: [
      {
        type: 'text',
        text: 'Kyoto is known for its beautiful temples, traditional tea houses, and gardens. Some popular attractions include Kinkaku-ji (Golden Pavilion) with its stunning gold leaf exterior reflecting in the mirror pond, Fushimi Inari Shrine with its thousands of vermilion torii gates winding up the mountainside, Arashiyama Bamboo Grove where towering stalks create an otherworldly atmosphere, Kiyomizu-dera Temple perched on a hillside offering panoramic views of the city, and the historic Gion district where you might spot geisha hurrying to evening appointments through narrow stone-paved streets lined with traditional wooden machiya houses.'
      }
    ]
  }
])
</script>

<template>
  <UChatMessages
    :auto-scroll="{
      color: 'neutral',
      variant: 'outline'
    }"
    :should-scroll-to-bottom="false"
    :messages="messages"
  />
</template>
<script setup lang="ts">
import { ref, h } from 'vue'

const messages = ref([
  {
    id: '6045235a-a435-46b8-989d-2df38ca2eb47',
    role: 'user',
    parts: [
      {
        type: 'text',
        text: 'Hello, how are you?'
      }
    ]
  },
  {
    id: '7a92b3c1-d5f8-4e76-b8a9-3c1e5fb2e0d8',
    role: 'assistant',
    parts: [
      {
        type: 'text',
        text: 'I am doing well, thank you for asking! How can I assist you today?'
      }
    ]
  },
  {
    id: '9c84d6a7-8b23-4f12-a1d5-e7f3b9c05e2a',
    role: 'user',
    parts: [
      {
        type: 'text',
        text: 'What is the current weather in Tokyo?'
      }
    ]
  },
  {
    id: 'b2e5f8c3-a1d9-4e67-b3f2-c9d8e7a6b5f4',
    role: 'assistant',
    parts: [
      {
        type: 'text',
        text: "Based on the latest data, Tokyo is currently experiencing sunny weather with temperatures around 24°C (75°F). It's a beautiful day with clear skies. The forecast for the rest of the week shows a slight chance of rain on Thursday, with temperatures gradually rising to 28°C by the weekend. Humidity levels are moderate at around 65%, and wind speeds are light at 8 km/h from the southeast. Air quality is good with an index of 42. The UV index is high at 7, so it's recommended to wear sunscreen if you're planning to spend time outdoors. Sunrise was at 5:24 AM and sunset will be at 6:48 PM, giving Tokyo approximately 13 hours and 24 minutes of daylight today. The moon is currently in its waxing gibbous phase."
      }
    ]
  },
  {
    id: 'c3e5f8c3-a1d9-4e67-b3f2-c9d8e7a6b5f4',
    role: 'user',
    parts: [
      {
        type: 'text',
        text: 'Can you recommend some popular tourist attractions in Kyoto?'
      }
    ]
  },
  {
    id: 'd4f5g8c3-a1d9-4e67-b3f2-c9d8e7a6b5f4',
    role: 'assistant',
    parts: [
      {
        type: 'text',
        text: 'Kyoto is known for its beautiful temples, traditional tea houses, and gardens. Some popular attractions include Kinkaku-ji (Golden Pavilion) with its stunning gold leaf exterior reflecting in the mirror pond, Fushimi Inari Shrine with its thousands of vermilion torii gates winding up the mountainside, Arashiyama Bamboo Grove where towering stalks create an otherworldly atmosphere, Kiyomizu-dera Temple perched on a hillside offering panoramic views of the city, and the historic Gion district where you might spot geisha hurrying to evening appointments through narrow stone-paved streets lined with traditional wooden machiya houses.'
      }
    ]
  }
])
</script>

<template>
  <UChatMessages
    :auto-scroll="{
      color: 'neutral',
      variant: 'outline'
    }"
    :should-scroll-to-bottom="false"
    :messages="messages"
  />
</template>

Auto scrollen pictogram

Gebruik de auto-scroll-icon-prop om de automatische scrollknop aan te passen Icon. Standaard i-lucide-arrow-down.

Hello, how are you?
I am doing well, thank you for asking! How can I assist you today?
What is the current weather in Tokyo?
Based on the latest data, Tokyo is currently experiencing sunny weather with temperatures around 24°C (75°F). It's a beautiful day with clear skies. The forecast for the rest of the week shows a slight chance of rain on Thursday, with temperatures gradually rising to 28°C by the weekend. Humidity levels are moderate at around 65%, and wind speeds are light at 8 km/h from the southeast. Air quality is good with an index of 42. The UV index is high at 7, so it's recommended to wear sunscreen if you're planning to spend time outdoors. Sunrise was at 5:24 AM and sunset will be at 6:48 PM, giving Tokyo approximately 13 hours and 24 minutes of daylight today. The moon is currently in its waxing gibbous phase.
Can you recommend some popular tourist attractions in Kyoto?
Kyoto is known for its beautiful temples, traditional tea houses, and gardens. Some popular attractions include Kinkaku-ji (Golden Pavilion) with its stunning gold leaf exterior reflecting in the mirror pond, Fushimi Inari Shrine with its thousands of vermilion torii gates winding up the mountainside, Arashiyama Bamboo Grove where towering stalks create an otherworldly atmosphere, Kiyomizu-dera Temple perched on a hillside offering panoramic views of the city, and the historic Gion district where you might spot geisha hurrying to evening appointments through narrow stone-paved streets lined with traditional wooden machiya houses.
<script setup lang="ts">
const messages = ref([
  {
    id: '6045235a-a435-46b8-989d-2df38ca2eb47',
    role: 'user',
    parts: [
      {
        type: 'text',
        text: 'Hello, how are you?'
      }
    ]
  },
  {
    id: '7a92b3c1-d5f8-4e76-b8a9-3c1e5fb2e0d8',
    role: 'assistant',
    parts: [
      {
        type: 'text',
        text: 'I am doing well, thank you for asking! How can I assist you today?'
      }
    ]
  },
  {
    id: '9c84d6a7-8b23-4f12-a1d5-e7f3b9c05e2a',
    role: 'user',
    parts: [
      {
        type: 'text',
        text: 'What is the current weather in Tokyo?'
      }
    ]
  },
  {
    id: 'b2e5f8c3-a1d9-4e67-b3f2-c9d8e7a6b5f4',
    role: 'assistant',
    parts: [
      {
        type: 'text',
        text: "Based on the latest data, Tokyo is currently experiencing sunny weather with temperatures around 24°C (75°F). It's a beautiful day with clear skies. The forecast for the rest of the week shows a slight chance of rain on Thursday, with temperatures gradually rising to 28°C by the weekend. Humidity levels are moderate at around 65%, and wind speeds are light at 8 km/h from the southeast. Air quality is good with an index of 42. The UV index is high at 7, so it's recommended to wear sunscreen if you're planning to spend time outdoors. Sunrise was at 5:24 AM and sunset will be at 6:48 PM, giving Tokyo approximately 13 hours and 24 minutes of daylight today. The moon is currently in its waxing gibbous phase."
      }
    ]
  },
  {
    id: 'c3e5f8c3-a1d9-4e67-b3f2-c9d8e7a6b5f4',
    role: 'user',
    parts: [
      {
        type: 'text',
        text: 'Can you recommend some popular tourist attractions in Kyoto?'
      }
    ]
  },
  {
    id: 'd4f5g8c3-a1d9-4e67-b3f2-c9d8e7a6b5f4',
    role: 'assistant',
    parts: [
      {
        type: 'text',
        text: 'Kyoto is known for its beautiful temples, traditional tea houses, and gardens. Some popular attractions include Kinkaku-ji (Golden Pavilion) with its stunning gold leaf exterior reflecting in the mirror pond, Fushimi Inari Shrine with its thousands of vermilion torii gates winding up the mountainside, Arashiyama Bamboo Grove where towering stalks create an otherworldly atmosphere, Kiyomizu-dera Temple perched on a hillside offering panoramic views of the city, and the historic Gion district where you might spot geisha hurrying to evening appointments through narrow stone-paved streets lined with traditional wooden machiya houses.'
      }
    ]
  }
])
</script>

<template>
  <UChatMessages
    auto-scroll-icon="i-lucide-chevron-down"
    :should-scroll-to-bottom="false"
    :messages="messages"
  />
</template>
<script setup lang="ts">
import { ref, h } from 'vue'

const messages = ref([
  {
    id: '6045235a-a435-46b8-989d-2df38ca2eb47',
    role: 'user',
    parts: [
      {
        type: 'text',
        text: 'Hello, how are you?'
      }
    ]
  },
  {
    id: '7a92b3c1-d5f8-4e76-b8a9-3c1e5fb2e0d8',
    role: 'assistant',
    parts: [
      {
        type: 'text',
        text: 'I am doing well, thank you for asking! How can I assist you today?'
      }
    ]
  },
  {
    id: '9c84d6a7-8b23-4f12-a1d5-e7f3b9c05e2a',
    role: 'user',
    parts: [
      {
        type: 'text',
        text: 'What is the current weather in Tokyo?'
      }
    ]
  },
  {
    id: 'b2e5f8c3-a1d9-4e67-b3f2-c9d8e7a6b5f4',
    role: 'assistant',
    parts: [
      {
        type: 'text',
        text: "Based on the latest data, Tokyo is currently experiencing sunny weather with temperatures around 24°C (75°F). It's a beautiful day with clear skies. The forecast for the rest of the week shows a slight chance of rain on Thursday, with temperatures gradually rising to 28°C by the weekend. Humidity levels are moderate at around 65%, and wind speeds are light at 8 km/h from the southeast. Air quality is good with an index of 42. The UV index is high at 7, so it's recommended to wear sunscreen if you're planning to spend time outdoors. Sunrise was at 5:24 AM and sunset will be at 6:48 PM, giving Tokyo approximately 13 hours and 24 minutes of daylight today. The moon is currently in its waxing gibbous phase."
      }
    ]
  },
  {
    id: 'c3e5f8c3-a1d9-4e67-b3f2-c9d8e7a6b5f4',
    role: 'user',
    parts: [
      {
        type: 'text',
        text: 'Can you recommend some popular tourist attractions in Kyoto?'
      }
    ]
  },
  {
    id: 'd4f5g8c3-a1d9-4e67-b3f2-c9d8e7a6b5f4',
    role: 'assistant',
    parts: [
      {
        type: 'text',
        text: 'Kyoto is known for its beautiful temples, traditional tea houses, and gardens. Some popular attractions include Kinkaku-ji (Golden Pavilion) with its stunning gold leaf exterior reflecting in the mirror pond, Fushimi Inari Shrine with its thousands of vermilion torii gates winding up the mountainside, Arashiyama Bamboo Grove where towering stalks create an otherworldly atmosphere, Kiyomizu-dera Temple perched on a hillside offering panoramic views of the city, and the historic Gion district where you might spot geisha hurrying to evening appointments through narrow stone-paved streets lined with traditional wooden machiya houses.'
      }
    ]
  }
])
</script>

<template>
  <UChatMessages
    auto-scroll-icon="i-lucide-chevron-down"
    :should-scroll-to-bottom="false"
    :messages="messages"
  />
</template>
U kunt dit pictogram globaal aanpassen in uw app.config.ts onder ui.icons.arrowDown-sleutel.
U kunt dit pictogram globaal aanpassen in uw vite.config.ts onder ui.icons.arrowDown-sleutel.

Moet automatisch scrollen

Gebruik de should-auto-scroll-prop om continu automatisch scrollen in / uit te schakelen terwijl berichten worden gestreamd. Standaard false.

<template>
  <UChatMessages :messages="messages" should-auto-scroll />
</template>

Moet naar beneden scrollen

Gebruik de should-scroll-to-bottom-prop om automatisch scrollen onder in / uit te schakelen wanneer het onderdeel is gemonteerd. Standaard true.

<template>
  <UChatMessages :messages="messages" :should-scroll-to-bottom="false" />
</template>

Voorbeelden

Bekijk de Chat overzichtspagina voor installatie-instructies, serverinstellingen en gebruiksvoorbeelden.

Met indicatorsleuf

Gebruik de #indicator-sleuf om de laadindicator aan te passen met een ChatShimmer effect.

Hello! Can you help me with something?
Searching...
<script setup lang="ts">
import type { UIMessage } from 'ai'
import { useChat } from '@ai-sdk/vue'

const initialMessages: UIMessage[] = [{
  id: '1',
  role: 'user',
  parts: [{ type: 'text', text: 'Hello! Can you help me with something?' }]
}]

const { messages } = useChat({
  messages: initialMessages
})

const size = 4
const gap = 2
const totalDots = size * size

const patterns = [
  [[0], [1], [2], [3], [7], [11], [15], [14], [13], [12], [8], [4], [5], [6], [10], [9]],
  [[0, 4, 8, 12], [1, 5, 9, 13], [2, 6, 10, 14], [3, 7, 11, 15]],
  [[5, 6, 9, 10], [1, 4, 7, 8, 11, 14], [0, 3, 12, 15], [1, 4, 7, 8, 11, 14], [5, 6, 9, 10]],
  [[0], [1, 4], [2, 5, 8], [3, 6, 9, 12], [7, 10, 13], [11, 14], [15]]
]

const activeDots = ref<Set<number>>(new Set())
let patternIndex = 0
let stepIndex = 0

function nextStep() {
  const pattern = patterns[patternIndex]
  if (!pattern) return

  activeDots.value = new Set(pattern[stepIndex])
  stepIndex++

  if (stepIndex >= pattern.length) {
    stepIndex = 0
    patternIndex = (patternIndex + 1) % patterns.length
  }
}

const statusMessages = ['Searching...', 'Reading...', 'Analyzing...', 'Thinking...']
const currentIndex = ref(0)
const displayedText = ref(statusMessages[0]!)
const chars = 'abcdefghijklmnopqrstuvwxyz'

function scramble(from: string, to: string) {
  const maxLength = Math.max(from.length, to.length)
  let frame = 0
  const totalFrames = 15

  const step = () => {
    frame++
    let result = ''
    const progress = (frame / totalFrames) * maxLength

    for (let i = 0; i < maxLength; i++) {
      if (i < progress - 2) {
        result += to[i] || ''
      } else if (i < progress) {
        result += chars[Math.floor(Math.random() * chars.length)]
      } else {
        result += from[i] || ''
      }
    }

    displayedText.value = result

    if (frame < totalFrames) {
      requestAnimationFrame(step)
    } else {
      displayedText.value = to
    }
  }

  requestAnimationFrame(step)
}

let matrixInterval: ReturnType<typeof setInterval> | undefined
let textInterval: ReturnType<typeof setInterval> | undefined

onMounted(() => {
  nextStep()
  matrixInterval = setInterval(nextStep, 120)
  textInterval = setInterval(() => {
    const prev = displayedText.value
    currentIndex.value = (currentIndex.value + 1) % statusMessages.length
    scramble(prev, statusMessages[currentIndex.value]!)
  }, 3000)
})

onUnmounted(() => {
  clearInterval(matrixInterval)
  clearInterval(textInterval)
})
</script>

<template>
  <UChatMessages
    :messages="messages"
    status="submitted"
    :should-scroll-to-bottom="false"
  >
    <template #indicator>
      <div class="flex items-center gap-2 text-muted overflow-hidden">
        <div
          class="shrink-0 grid size-4"
          :style="{
            gridTemplateColumns: `repeat(${size}, 1fr)`,
            gap: `${gap}px`
          }"
        >
          <span
            v-for="i in totalDots"
            :key="i"
            class="rounded-sm bg-current transition-opacity duration-100"
            :class="activeDots.has(i - 1) ? 'opacity-100' : 'opacity-20'"
          />
        </div>

        <UChatShimmer :text="displayedText" class="text-sm font-mono" />
      </div>
    </template>
  </UChatMessages>
</template>
<script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue'
import type { UIMessage } from 'ai'
import { useChat } from '@ai-sdk/vue'

const initialMessages: UIMessage[] = [{
  id: '1',
  role: 'user',
  parts: [{ type: 'text', text: 'Hello! Can you help me with something?' }]
}]

const { messages } = useChat({
  messages: initialMessages
})

const size = 4
const gap = 2
const totalDots = size * size

const patterns = [
  [[0], [1], [2], [3], [7], [11], [15], [14], [13], [12], [8], [4], [5], [6], [10], [9]],
  [[0, 4, 8, 12], [1, 5, 9, 13], [2, 6, 10, 14], [3, 7, 11, 15]],
  [[5, 6, 9, 10], [1, 4, 7, 8, 11, 14], [0, 3, 12, 15], [1, 4, 7, 8, 11, 14], [5, 6, 9, 10]],
  [[0], [1, 4], [2, 5, 8], [3, 6, 9, 12], [7, 10, 13], [11, 14], [15]]
]

const activeDots = ref<Set<number>>(new Set())
let patternIndex = 0
let stepIndex = 0

function nextStep() {
  const pattern = patterns[patternIndex]
  if (!pattern) return

  activeDots.value = new Set(pattern[stepIndex])
  stepIndex++

  if (stepIndex >= pattern.length) {
    stepIndex = 0
    patternIndex = (patternIndex + 1) % patterns.length
  }
}

const statusMessages = ['Searching...', 'Reading...', 'Analyzing...', 'Thinking...']
const currentIndex = ref(0)
const displayedText = ref(statusMessages[0]!)
const chars = 'abcdefghijklmnopqrstuvwxyz'

function scramble(from: string, to: string) {
  const maxLength = Math.max(from.length, to.length)
  let frame = 0
  const totalFrames = 15

  const step = () => {
    frame++
    let result = ''
    const progress = (frame / totalFrames) * maxLength

    for (let i = 0; i < maxLength; i++) {
      if (i < progress - 2) {
        result += to[i] || ''
      } else if (i < progress) {
        result += chars[Math.floor(Math.random() * chars.length)]
      } else {
        result += from[i] || ''
      }
    }

    displayedText.value = result

    if (frame < totalFrames) {
      requestAnimationFrame(step)
    } else {
      displayedText.value = to
    }
  }

  requestAnimationFrame(step)
}

let matrixInterval: ReturnType<typeof setInterval> | undefined
let textInterval: ReturnType<typeof setInterval> | undefined

onMounted(() => {
  nextStep()
  matrixInterval = setInterval(nextStep, 120)
  textInterval = setInterval(() => {
    const prev = displayedText.value
    currentIndex.value = (currentIndex.value + 1) % statusMessages.length
    scramble(prev, statusMessages[currentIndex.value]!)
  }, 3000)
})

onUnmounted(() => {
  clearInterval(matrixInterval)
  clearInterval(textInterval)
})
</script>

<template>
  <UChatMessages
    :messages="messages"
    status="submitted"
    :should-scroll-to-bottom="false"
  >
    <template #indicator>
      <div class="flex items-center gap-2 text-muted overflow-hidden">
        <div
          class="shrink-0 grid size-4"
          :style="{
            gridTemplateColumns: `repeat(${size}, 1fr)`,
            gap: `${gap}px`
          }"
        >
          <span
            v-for="i in totalDots"
            :key="i"
            class="rounded-sm bg-current transition-opacity duration-100"
            :class="activeDots.has(i - 1) ? 'opacity-100' : 'opacity-20'"
          />
        </div>

        <UChatShimmer :text="displayedText" class="text-sm font-mono" />
      </div>
    </template>
  </UChatMessages>
</template>

API

Props

Prop Default Type
messages
T
status
"submitted" | "streaming" | "ready" | "error"
shouldAutoScroll
false
boolean

Whether to automatically scroll to the bottom when a message is streaming.

shouldScrollToBottom
true
boolean

Whether to scroll to the bottom on mounted.

autoScroll
true
boolean | Omit<ButtonProps, LinkPropsKeys>

Display an auto scroll button. { size: 'md', color: 'neutral', variant: 'outline' }

autoScrollIcon
appConfig.ui.icons.arrowDown
any

The icon displayed in the auto scroll button.

user
Pick<PropsBase<T>, "actions" | "ui" | "color" | "variant" | "icon" | "avatar" | "side">

The user messages props. { side: 'right', variant: 'soft' }

assistant
Pick<PropsBase<T>, "actions" | "ui" | "color" | "variant" | "icon" | "avatar" | "side">

The assistant messages props. { side: 'left', variant: 'naked' }

compact
false
boolean

Render the messages in a compact style. This is done automatically when used inside a UChatPalette.

spacingOffset
0
number

The spacing offset for the last message in px. Can be useful when the prompt is sticky for example.

ui
{ root?: SlotClass; indicator?: SlotClass; viewport?: SlotClass; autoScroll?: SlotClass; }

Slots

Slot Type
default
{ registerMessageRef: (id: string, element: ComponentPublicInstance | null) => void; }
indicator
{ ui: object; }
viewport
{ ui: object; }
header
UIMessage<unknown, UIDataTypes, UITools> & { message: MessageBase<T>; }
leading
UIMessage<unknown, UIDataTypes, UITools> & { avatar: (AvatarProps & { [key: string]: any; }) | undefined; ui: object; } & { message: MessageBase<T>; }
files
Omit<UIMessage<unknown, UIDataTypes, UITools>, "parts"> & { parts: FileUIPart[]; } & { message: MessageBase<T>; }
body
UIMessage<unknown, UIDataTypes, UITools> & { message: MessageBase<T>; }
content
UIMessage<unknown, UIDataTypes, UITools> & { content?: string | undefined; } & { message: MessageBase<T>; }
actions
UIMessage<unknown, UIDataTypes, UITools> & { actions: (Omit<ButtonProps, "onClick"> & { onClick?: ((e: MouseEvent, message: UIMessage<unknown, UIDataTypes, UITools>) => void) | undefined; })[] | undefined; } & { message: MessageBase<T>; }
U kunt alle slots van de ChatMessage component in ChatMessages gebruiken, ze worden automatisch doorgestuurd, zodat u individuele berichten kunt aanpassen wanneer u de messages-prop gebruikt.
<script setup lang="ts">
import { isTextUIPart } from 'ai'
</script>

<template>
  <UChatMessages :messages="messages" :status="status">
    <template #content="{ message }">
      <template
        v-for="(part, index) in message.parts"
        :key="`${message.id}-${part.type}-${index}`"
      >
        <p v-if="isTextUIPart(part)" class="whitespace-pre-wrap">
          {{ part.text }}
        </p>
      </template>
    </template>
  </UChatMessages>
</template>

Expose

Wanneer u de component opent via een sjabloonref, kunt u het volgende gebruiken:

NaamType
registerMessageRef(id: string, element: ComponentPublicInstance | null)void

Thema

app.config.ts
export default defineAppConfig({
  ui: {
    chatMessages: {
      slots: {
        root: 'w-full flex flex-col gap-1 flex-1 px-2.5 [&>article]:last-of-type:min-h-(--last-message-height)',
        indicator: 'h-6 flex items-center gap-1 py-3 *:size-2 *:rounded-full *:bg-elevated motion-safe:[&>*:nth-child(1)]:animate-[bounce_1s_infinite] motion-safe:[&>*:nth-child(2)]:animate-[bounce_1s_0.15s_infinite] motion-safe:[&>*:nth-child(3)]:animate-[bounce_1s_0.3s_infinite]',
        viewport: 'absolute inset-x-0 top-[86%] data-[state=open]:animate-[fade-in_200ms_var(--ease-out)] data-[state=closed]:animate-[fade-out_200ms_var(--ease-out)]',
        autoScroll: 'rounded-full absolute right-1/2 translate-x-1/2 bottom-0'
      },
      variants: {
        compact: {
          true: '',
          false: ''
        }
      }
    }
  }
})
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: {
        chatMessages: {
          slots: {
            root: 'w-full flex flex-col gap-1 flex-1 px-2.5 [&>article]:last-of-type:min-h-(--last-message-height)',
            indicator: 'h-6 flex items-center gap-1 py-3 *:size-2 *:rounded-full *:bg-elevated motion-safe:[&>*:nth-child(1)]:animate-[bounce_1s_infinite] motion-safe:[&>*:nth-child(2)]:animate-[bounce_1s_0.15s_infinite] motion-safe:[&>*:nth-child(3)]:animate-[bounce_1s_0.3s_infinite]',
            viewport: 'absolute inset-x-0 top-[86%] data-[state=open]:animate-[fade-in_200ms_var(--ease-out)] data-[state=closed]:animate-[fade-out_200ms_var(--ease-out)]',
            autoScroll: 'rounded-full absolute right-1/2 translate-x-1/2 bottom-0'
          },
          variants: {
            compact: {
              true: '',
              false: ''
            }
          }
        }
      }
    })
  ]
})

Wijzigingsgelog

No recent changes