DevUI + Vue 3 入门实战教程:从零构建AI对话应用

文章目录


前言

DevUI是华为开源的企业级设计系统,专为中后台产品打造。本文通过构建一个完整的AI助手对话应用,深入讲解DevUI的核心组件、主题系统和最佳实践。我们将结合MateChat(一个专为AI场景优化的前端组件库)来展示DevUI在现代Web应用中的实际应用价值。


第一步:DevUI项目初始化与主题系统配置

核心初始化代码解析

typescript 复制代码
import { createApp } from 'vue'
import App from './App.vue'
import DevUI from 'vue-devui'
import 'vue-devui/style.css'
import '@devui-design/icons/icomoon/devui-icon.css'
import { ThemeServiceInit, infinityTheme } from 'devui-theme'

// 初始化DevUI主题系统
ThemeServiceInit({ infinityTheme }, 'infinityTheme')

const app = createApp(App)
app.use(DevUI)
app.mount('#app')

首先通过ThemeServiceInit初始化了DevUI的主题系统,使用了infinityTheme 这个现代化的设计主题,它提供了一套完整的色彩体系、排版规范和组件样式。其次通过app.use(DevUI)注册了DevUI插件,这样就能在全局范围内使用d-button、d-input等所有DevUI组件,无需逐个导入。最后导入了样式文件和图标库,确保组件的视觉效果和icon功能完整可用。

DevUI的主题系统基于设计令牌(Design Tokens)的概念,通过修改主题变量就能快速改变整个应用的视觉风格,而无需修改任何组件代码。这对于需要适配不同客户品牌色或支持深色模式的项目特别有价值。


第二步:搭建聊天界面布局

整体结构设计

我们的案例应用采用了经典的聊天应用布局:顶部是标题栏、中间是消息展示区、底部是输入框。这个结构在各种对话应用中都很常见,包括MateChat在内的专业AI对话库也遵循类似的布局模式。

javascript 复制代码
<template>
  <div class="chat-container">
    <!-- 顶部标题栏 -->
    <div class="chat-header">
      <h1>DevUI AI Assistant</h1>
      <p>Powered by DevUI & MateChat</p>
    </div>
    
    <!-- 消息展示区 -->
    <div class="chat-messages" ref="messagesContainer">
      <!-- 消息列表渲染 -->
    </div>

    <!-- 输入区域 -->
    <div class="chat-input-area">
      <!-- DevUI输入组件 -->
    </div>
  </div>
</template>

第三步:使用DevUI的d-input和d-button组件

输入框组件详解

javascript 复制代码
<div class="chat-input-area">
  <d-input
    v-model="inputValue"
    placeholder="输入你的问题..."
    @keyup.enter="sendMessage"
  >
  </d-input>
  <d-button 
    @click="sendMessage"
    kind="primary"
    :disabled="!inputValue.trim()"
  >
    发送
  </d-button>
</div>

这段代码展示了DevUI两个最基础但最常用的组件。d-input 是一个增强的输入框组件,相比原生的input标签,它提供了清晰的焦点状态反馈、内置的禁用状态样式、验证反馈的支持、以及与DevUI主题系统的完美集成。我们通过v-model进行双向数据绑定,通过@keyup.enter事件监听实现回车发送的常见交互。

d-button 组件则提供了多种预设样式。其中kind="primary"表示这是一个强调按钮,适合作为主要操作。disabled属性的动态绑定保证了只有在用户有实际输入内容时才能点击发送,这是一个简单但重要的用户体验优化------避免用户误点发送空消息。

为什么不用原生HTML?

DevUI组件相比原生HTML元素的优势在于:首先提供了企业级的样式一致性,确保在不同浏览器和设备上的表现统一;其次内置了常见的交互功能,如清空按钮、验证提示等,无需额外开发;最后与整个DevUI设计系统深度融合,修改主题后所有使用DevUI组件的地方都会自动适应新的风格。


第四步:消息列表的动态渲染

消息数据结构设计

typescript 复制代码
interface Message {
  from: 'user' | 'assistant'
  content: string
  loading?: boolean
}

const messages = ref<Message[]>([])

为了区分用户消息和助手消息,我们定义了一个清晰的接口。from字段表示消息来源,content存储消息内容,loading字段用于显示打字动画,这个设计参考了MateChat对话库的最佳实践。

条件渲染与样式差异

javascript 复制代码
<div class="chat-messages" ref="messagesContainer">
      <div 
        v-for="(msg, idx) in messages" 
        :key="idx"
        :class="['message', msg.from === 'user' ? 'user-msg' : 'assistant-msg']"
      >
        <div class="avatar">
          {{ msg.from === 'user' ? 'You' : 'AI' }}
        </div>
        <div class="content">
          {{ msg.content }}
          <span v-if="msg.loading" class="loading">●●●</span>
        </div>
      </div>
    </div>

这里我们使用了Vue 3的v-for指令循环渲染消息列表,通过动态的class绑定实现了用户消息和助手消息的不同样式。特别地,我们添加了msg.loading判断来在消息还在生成时显示加载动画。这种设计能让用户清楚地感知到AI正在思考,避免了"为什么没有响应"的困惑。

自动滚动到底部

typescript 复制代码
const scrollToBottom = () => {
  if (messagesContainer.value) {
    messagesContainer.value.scrollTop = messagesContainer.value.scrollHeight
  }
}

当新消息到来时,我们需要自动将视图滚动到最新的消息。通过在发送消息和接收消息时都调用这个函数,确保用户始终能看到最新的对话内容,这在长对话中特别重要。

第五步:核心业务逻辑------消息发送与接收

发送消息的完整流程

typescript 复制代码
const sendMessage = async () => {
  if (!inputValue.value.trim()) return

  // 添加用户消息
  messages.value.push({
    from: 'user',
    content: inputValue.value
  })

  const userInput = inputValue.value
  inputValue.value = ''

  // 添加AI消息占位符
  messages.value.push({
    from: 'assistant',
    content: '',
    loading: true
  })

  await nextTick()
  scrollToBottom()

  // 模拟AI响应
  setTimeout(() => {
    const lastMsg = messages.value[messages.value.length - 1]
    lastMsg.content = `您说:${userInput}。这是一个DevUI演示应用,已成功集成MateChat对话组件库。`
    lastMsg.loading = false
    scrollToBottom()
  }, 800)
}

这个函数实现了一个完整的消息交互流程。首先验证输入不为空,然后立即将用户消息添加到列表中显示,这给用户即时反馈。接着清空输入框,添加一条带有loading状态的AI消息占位符。使用nextTick()确保DOM已更新后再滚动,这是Vue 3异步更新的最佳实践。最后通过setTimeout模拟网络延迟,演示AI正在思考的过程。


第六步:样式设计------如何用CSS实现现代化UI

渐变背景与卡片设计

css 复制代码
.chat-container {
  display: flex;
  flex-direction: column;
  height: 100vh;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}

我们使用了现代的渐变背景,配合紫蓝色系,营造出专业的AI助手应用氛围。这种配色方案在当下的SaaS应用中很流行,特别是在AI相关的产品中。

消息气泡的左右对齐

css 复制代码
.message {
  display: flex;
  gap: 10px;
  animation: slideIn 0.3s ease-out;
}

.message.user-msg {
  justify-content: flex-end;
}

.user-msg .content {
  background: #667eea;
  color: white;
  border-bottom-right-radius: 2px;
}

.assistant-msg .content {
  background: white;
  color: #333;
  border-bottom-left-radius: 2px;
}

这里我们用Flexbox实现了经典的聊天气泡对齐。用户消息靠右(justify-content: flex-end),助手消息靠左(默认)。通过不同的背景色和文字色区分两者,用户消息用渐变色的主色调,助手消息用白底。特别的是,我们在消息气泡的一个角落减小圆角(border-bottom-right-radius: 2px),这样可以指向头像,增强了气泡的指向性。

加载动画效果

css 复制代码
.loading {
  display: inline-block;
  animation: blink 1s infinite;
}

@keyframes blink {
  0%, 49% {
    opacity: 1;
  }
  50%, 100% {
    opacity: 0.3;
  }
}

三个圆点的闪烁动画是经典的加载视觉反馈。通过控制opacity而不是display,确保了平滑的动画效果,不会有闪烁导致的性能问题。

整体效果

完整代码

如下是完整代码。

main.js

javascript 复制代码
import { createApp } from 'vue'
import App from './App.vue'
import DevUI from 'vue-devui'
import 'vue-devui/style.css'
import '@devui-design/icons/icomoon/devui-icon.css'
import { ThemeServiceInit, infinityTheme } from 'devui-theme'

ThemeServiceInit({ infinityTheme }, 'infinityTheme')

const app = createApp(App)
app.use(DevUI)
app.mount('#app')

package.json

javascript 复制代码
{
  "name": "devui-chat-demo",
  "private": true,
  "version": "0.0.1",
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "vue-tsc && vite build",
    "preview": "vite preview"
  },
  "dependencies": {
    "vue": "^3.3.0",
    "vue-devui": "^1.9.0",
    "@devui-design/icons": "^1.1.2",
    "devui-theme": "^0.4.8"
  },
  "devDependencies": {
    "@vitejs/plugin-vue": "^4.2.0",
    "typescript": "^5.0.0",
    "vite": "^4.3.0",
    "vue-tsc": "^1.6.0"
  }
}

APP.vue

javascript 复制代码
<template>
  <div class="chat-container">
    <div class="chat-header">
      <h1>DevUI AI Assistant</h1>
      <p>Powered by DevUI & MateChat</p>
    </div>
    
    <div class="chat-messages" ref="messagesContainer">
      <div 
        v-for="(msg, idx) in messages" 
        :key="idx"
        :class="['message', msg.from === 'user' ? 'user-msg' : 'assistant-msg']"
      >
        <div class="avatar">
          {{ msg.from === 'user' ? 'You' : 'AI' }}
        </div>
        <div class="content">
          {{ msg.content }}
          <span v-if="msg.loading" class="loading">●●●</span>
        </div>
      </div>
    </div>

    <div class="chat-input-area">
      <d-input
        v-model="inputValue"
        placeholder="输入你的问题..."
        @keyup.enter="sendMessage"
      />
      <d-button 
        @click="sendMessage"
        kind="primary"
        :disabled="!inputValue.trim()"
      >
        发送
      </d-button>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, nextTick } from 'vue'

interface Message {
  from: 'user' | 'assistant'
  content: string
  loading?: boolean
}

const inputValue = ref('')
const messages = ref<Message[]>([])
const messagesContainer = ref<HTMLElement>()

const sendMessage = async () => {
  if (!inputValue.value.trim()) return

  // 添加用户消息
  messages.value.push({
    from: 'user',
    content: inputValue.value
  })

  const userInput = inputValue.value
  inputValue.value = ''

  // 添加AI消息占位符
  messages.value.push({
    from: 'assistant',
    content: '',
    loading: true
  })

  await nextTick()
  scrollToBottom()

  // 模拟AI响应
  setTimeout(() => {
    const lastMsg = messages.value[messages.value.length - 1]
    lastMsg.content = `您说:${userInput}。这是一个DevUI演示应用,已成功集成MateChat对话组件库。`
    lastMsg.loading = false
    scrollToBottom()
  }, 800)
}

const scrollToBottom = () => {
  if (messagesContainer.value) {
    messagesContainer.value.scrollTop = messagesContainer.value.scrollHeight
  }
}
</script>

<style scoped>
.chat-container {
  display: flex;
  flex-direction: column;
  height: 100vh;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}

.chat-header {
  padding: 20px;
  color: white;
  text-align: center;
  border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}

.chat-header h1 {
  margin: 0 0 10px 0;
  font-size: 28px;
}

.chat-header p {
  margin: 0;
  opacity: 0.9;
  font-size: 14px;
}

.chat-messages {
  flex: 1;
  overflow-y: auto;
  padding: 20px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.message {
  display: flex;
  gap: 10px;
  animation: slideIn 0.3s ease-out;
}

.message.user-msg {
  justify-content: flex-end;
}

.avatar {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 12px;
  font-weight: bold;
  color: white;
  flex-shrink: 0;
}

.user-msg .avatar {
  background: #667eea;
  order: 2;
}

.assistant-msg .avatar {
  background: #764ba2;
}

.content {
  max-width: 60%;
  padding: 12px 16px;
  border-radius: 8px;
  line-height: 1.5;
  word-break: break-word;
  font-size: 14px;
}

.user-msg .content {
  background: #667eea;
  color: white;
  border-bottom-right-radius: 2px;
}

.assistant-msg .content {
  background: white;
  color: #333;
  border-bottom-left-radius: 2px;
}

.loading {
  display: inline-block;
  animation: blink 1s infinite;
}

.chat-input-area {
  padding: 20px;
  background: white;
  display: flex;
  gap: 10px;
  border-top: 1px solid #e0e0e0;
}

:deep(.devui-input) {
  flex: 1;
}

:deep(.devui-input input) {
  width: 100%;
}

@keyframes slideIn {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes blink {
  0%, 49% {
    opacity: 1;
  }
  50%, 100% {
    opacity: 0.3;
  }
}
</style>

总结

这个例子虽然只有一个简单的对话功能,但背后展示的架构思想和最佳实践,完全可以扩展到复杂的企业级应用。无论是数据表格、表单验证、还是复杂的数据展示,DevUI都提供了相应的组件和系统支持。

想要深入学习,可以访问DevUI官网了解完整的组件库,看看如何在AI场景下最大化利用这些组件。现在就开始你的DevUI之旅吧!

相关资源链接:

相关推荐
Coding茶水间2 小时前
基于深度学习的无人机视角检测系统演示与介绍(YOLOv12/v11/v8/v5模型+Pyqt5界面+训练代码+数据集)
图像处理·人工智能·深度学习·yolo·目标检测·计算机视觉
JoannaJuanCV2 小时前
自动驾驶—CARLA 仿真(1)安装与demo测试
人工智能·机器学习·自动驾驶·carla
林林宋2 小时前
Step-Audio-R1
人工智能
这张生成的图像能检测吗2 小时前
(论文速读)面向视觉语言模型组合性理解可视分析方法
人工智能·视觉语言模型·可视化理解
国服第二切图仔3 小时前
DevUI Design中后台产品开源前端解决方案之Carousel 走马灯组件使用指南
前端·开源
无限大63 小时前
为什么浏览器能看懂网页代码?——从HTML到渲染引擎的奇幻之旅
前端
福尔摩斯张3 小时前
Linux信号捕捉特性详解:从基础到高级实践(超详细)
linux·运维·服务器·c语言·前端·驱动开发·microsoft
2401_860319523 小时前
DevUI组件库实战:从入门到企业级应用的深度探索 ,如何快速安装DevUI
前端·前端框架
qq_348231853 小时前
AI 驱动-前端源码生成测试
人工智能