加载器

一个旋转加载器组件,用于在 AI 应用程序中指示加载状态。

Loader 组件提供旋转动画来指示 AI 应用程序中的加载状态。它包括可自定义的包装组件和底层图标,以便灵活使用。

使用 CLI 安装

AI Elements Vue
shadcn-vue CLI
npx ai-elements-vue@latest add loader

手动安装

将以下文件复制并粘贴到同一文件夹中。

Loader.vue
LoaderIcon.vue
index.ts
<script setup lang="ts">
import { cn } from '@repo/shadcn-vue/lib/utils'
import LoaderIcon from './LoaderIcon.vue'

interface Props {
  size?: number
  class?: string
}

const props = withDefaults(defineProps<Props>(), {
  size: 16,
})
</script>

<template>
  <div
    :class="cn('inline-flex animate-spin items-center justify-center', props.class)"
    v-bind="$attrs"
  >
    <LoaderIcon :size="props.size" />
  </div>
</template>

与 AI SDK 一起使用

构建一个简单的聊天应用,在响应流式传输之前通过使用 status === "submitted" 显示加载器。

将以下组件添加到你的前端:

pages/index.vue
<script lang="ts" setup>
import { useChat } from '@ai-sdk/vue'
import { cn } from '@repo/shadcn-vue/lib/utils'
import { ref } from 'vue'
import { Conversation, ConversationContent, ConversationScrollButton } from '@/components/ai-elements/conversation'
import { Loader } from '@/components/ai-elements/loader'
import { Message, MessageContent } from '@/components/ai-elements/message'
import { PromptInput, PromptInputSubmit, PromptInputTextarea } from '@/components/ai-elements/prompt-input'

const input = ref('')
const { messages, sendMessage, status } = useChat()

function handleSubmit(e: Event) {
  if (input.value.trim()) {
    sendMessage({ text: input.value })
    input.value = ''
  }
}
</script>

<template>
  <div
    class="max-w-4xl mx-auto p-6 relative size-full rounded-lg border h-[600px]"
  >
    <div class="flex flex-col h-full">
      <Conversation>
        <ConversationContent>
          <Message v-for="message in messages" :key="message.id" :from="message.role">
            <MessageContent>
              <template v-for="(part, i) in message.parts" :key="`${message.id}-${i}`">
                <div v-if="part.type === 'text'">
                  {{ part.text }}
                </div>
              </template>
            </MessageContent>
          </Message>
          <Loader v-if="status === 'submitted'" />
        </ConversationContent>
        <ConversationScrollButton />
      </Conversation>

      <PromptInput
        class="mt-4 w-full max-w-2xl mx-auto relative"
        @submit.prevent="handleSubmit"
      >
        <PromptInputTextarea
          v-model="input"
          placeholder="Say something..."
          class="pr-12"
        />
        <PromptInputSubmit
          :status="status === 'streaming' ? 'streaming' : 'ready'"
          :disabled="!input.trim()"
          class="absolute bottom-1 right-1"
        />
      </PromptInput>
    </div>
  </div>
</template>

将以下路由添加到你的后端:

api/chat/route.ts
import { convertToModelMessages, streamText, UIMessage } from 'ai'

// Allow streaming responses up to 30 seconds
export const maxDuration = 30

export async function POST(req: Request) {
  const { model, messages }: { messages: UIMessage[], model: string } = await req.json()

  const result = streamText({
    model: 'openai/gpt-4o',
    messages: convertToModelMessages(messages),
  })

  return result.toUIMessageStreamResponse()
}

特性

  • 使用 CSS 动画的简洁现代旋转动画
  • 通过 size prop 可配置大小
  • 通过 CSS 类可自定义样式
  • 内置 animate-spin 动画,具有适当的居中
  • 导出 AILoader 包装器和 LoaderIcon 以便灵活使用
  • 支持所有标准 HTML div 属性
  • 具有适当类型定义的 TypeScript 支持
  • 优化的 SVG 图标,具有多个不透明度级别以实现平滑动画
  • 使用 currentColor 以实现适当的主题集成
  • 响应式和可访问的设计

示例

不同大小

自定义样式

Props

<Loader />

sizenumber
16
加载器的大小(宽度和高度),单位为像素。默认为 16。
classstring
''
应用于组件的额外 CSS 类。