头图

基于vite6+vue3+deepseek+arco-design+markdown从0-1实战撸一款web版流式对话AI小助手。Vue3 集成 DeepSeek-Chat 聊天对话大模型。支持暗黑+浅色、代码高亮、本地会话缓存

https://www.bilibili.com/video/BV12RZMYnENE/?aid=114231567454...

技术栈

  • 技术框架:vite^6.2.0+vue^3.5.13+vue-router^4.5.0
  • AI框架:DeepSeek-R1 + OpenAI
  • 组件库:arco-design^2.57.0 (字节桌面端组件库)
  • 状态管理:pinia^3.0.1
  • 本地存储:pinia-plugin-persistedstate^4.2.0
  • 高亮插件:highlight.js^11.11.1
  • markdown解析:markdown-it

项目特点

  1. 流式响应:Vue3+DeepSeek实现逐行打字输出效果
  2. 丝滑极速:基于Vite6构建,接入DeepSeek,性能更优,聊天丝滑流畅
  3. 特色功能:支持各种代码高亮,利于展示和分享代码片段、支持暗黑+亮色主题模式
  4. 风格:采用arco-design组件库,风格统一,美观大气

项目结构目录

vue3-web-deepseek已经发布至我的原创作品小铺,感谢大家的支持。
Vue3+DeepSeek+ArcoDesign网页版AI流式对话模板

.env环境变量

# title
VITE_APP_TITLE = 'Vue3-Web-DeepSeek'

# port
VITE_PORT = 3001

# 运行时自动打开浏览器
VITE_OPEN = true

# 开启https
VITE_HTTPS = false

# 是否删除生产环境 console
VITE_DROP_CONSOLE = true

# DeepSeek API配置
# VITE_DEEPSEEK_API_KEY = 替换为你的 API Key
VITE_DEEPSEEK_BASE_URL = https://api.deepseek.com

布局模板

9a83ca4c0c46241828b0a30f3429cc5b_1289798-20250327115505595-1234060084.png

c2aa03fcf9003dc27fcd492ebae584ae_1289798-20250327115750425-183788210.png

<script setup>
  import Sidebar from '@/layouts/components/sidebar/index.vue'
</script>

<template>
  <div class="vu__container">
    <div class="vu__layout flexbox flex-col">
      <div class="vu__layout-body flex1 flexbox">
        <!-- 侧边栏 -->
        <Sidebar />

        <!-- 主面板 -->
        <div class="vu__layout-main flex1">
          <router-view v-slot="{ Component, route }">
            <keep-alive>
              <component :is="Component" :key="route.path" />
            </keep-alive>
          </router-view>
        </div>
      </div>
    </div>
  </div>
</template>

image.png

<template>
  <div class="vu__sidebar" :class="{'collapsed': appstate.config.collapsed}">
    <a-button class="vu__sidebar-collapse" shape="circle" @click="handleCollapse"></a-button>
    <aside class="vu__sidebar-aside flex1 flexbox flex-col">
      <div class="vu__aside-head">
        <router-link to="/" class="logo"><i class="iconfont ai-deepseek"></i><span class="fs-14 ff-ab">Vue3-WebSeek</span></router-link>
        <div class="btn-create flex-c mt-15" @click="handleCreate"><i class="iconfont ai-newchat fs-20"></i>新建对话</div>
      </div>
      <div class="vu__aside-navlinks flexbox flex-col">
        <div class="section-navitem" @click="toLink('/aihub')">
          <span class="icon flex-c"><icon-compass size="18" /></span>
          <div class="title">AI 导航</div>
        </div>
        <a-dropdown trigger="hover" :show-arrow="false" position="rt" :popup-offset="15" :content-style="{'min-width': '150px'}">
          <div class="section-navitem">
            <span class="icon flex-c"><icon-command size="18" /></span>
            <div class="title">AI 技能</div>
            <i class="iconfont ai-arrR c-999 fs-12"></i>
          </div>
          <template #content>
            <a-doption><i class="iconfont ai-aisousou"></i> AI搜索</a-doption>
            <a-doption><i class="iconfont ai-fanyi"></i> 快速翻译</a-doption>
            <a-doption><i class="iconfont ai-xiezuo"></i> 帮我写作</a-doption>
            <a-doption><i class="iconfont ai-tuxiang"></i> 图像生成</a-doption>
            <a-doption><i class="iconfont ai-aicode"></i> AI编程</a-doption>
          </template>
        </a-dropdown>
      </div>
      <a-divider style="margin: 0;" />
      <div class="vu__aside-sessions flex1 flexbox flex-col">
        <div class="vu__aside-navlinks">
          <div class="section-navitem plain">
            <span class="icon flex-c"><icon-message size="18" /></span>
            <div class="title">最近对话</div>
            <i class="clean iconfont ai-qingli" @click="handleClean"></i>
          </div>
        </div>
        <a-scrollbar :outer-style="{'height': '100%'}">
          <template v-if="sessionstate.session.length">
            <SessionList />
          </template>
          <template v-else>
            <a-empty description="暂无对话" />
          </template>
        </a-scrollbar>
      </div>
      <div class="vu__aside-navlinks" @click="toLink('/setting')">
        ...
      </div>
    </aside>
  </div>
</template>

vue3实现编辑框功能

0a39ccab23941b2b4fda9732d331e835_1289798-20250327125044922-1364409028.png

8028936148d3227c7ac69a36434dbf17_1289798-20250327125134308-2082004896.png

3b06741f55409e165fa31b48a03bc1e7_1289798-20250327125545142-2056676685.png

<template>
  <div class="v3ai__footbar flexbox flex-col">
    <!-- 技能栏 -->
    <div v-if="skillbar" class="v3ai__skills flexbox flex-alignc">
      ...
    </div>
    <!-- 编辑栏 -->
    <div class="v3ai__inputbox flexbox flex-col">
      <div class="v3ai__editor flexbox">
        <a-textarea v-model="editorText" :auto-size="autoSize" placeholder="有问题,尽管问" @input="handleInput" />
      </div>
      <!-- 操作栏 -->
      <div class="v3ai__tools flexbox flex-alignc">
        <div class="option flex1 flexbox">
          <div class="btn" :class="{'active': isDeep}" @click="isDeep =! isDeep"><i class="iconfont ai-deepthink"></i> 深度思考 (R1)</div>
          <div class="btn" :class="{'active': isNetwork}" @click="isNetwork =! isNetwork"><i class="iconfont ai-network"></i> 联网</div>
        </div>
        <a-dropdown trigger="hover" :show-arrow="false" position="lb" :content-style="{'min-width': '250px'}">
          <a-button shape="circle"><icon-attachment size="18" /></a-button>
          <template #content>
            ...
          </template>
        </a-dropdown>
        <a-tooltip content="添加图片" position="top" mini>
          <a-button shape="circle"><icon-image size="18" /></a-button>
        </a-tooltip>
        <a-dropdown :show-arrow="false" position="top" :popup-translate="[-10, -5]">
          <a-button shape="circle" style="background: none;"><icon-plus size="18" /></a-button>
          <template #content>
            <a-doption value="pyq"><icon-apps /> 文件</a-doption>
            <a-doption value="qq"><icon-apps /> PDF文档分析</a-doption>
            <a-doption value="qq"><icon-apps /> Word文档分析</a-doption>
            <a-doption value="qq"><icon-apps /> 网页总结</a-doption>
          </template>
        </a-dropdown>
        <a-divider direction="vertical" style="margin: 0 8px 0 5px;" />
        <a-button type="primary" shape="circle" :disabled="!editorText?.trim() || sessionstate.loading" @click="handleSubmit">
          <icon-arrow-up v-if="!sessionstate.loading" size="20" />
          <icon-loading v-else size="18" />
        </a-button>
      </div>
    </div>
  </div>
</template>

vue3实现流式ai打字效果

正常输出功能。

const completion = await openai.chat.completions.create({
  messages: [
    {role: 'user', content: editorValue}
  ],
  model: 'deepseek-chat', // deepseek-chat对话模型 deepseek-reasoner推理模型
  stream: false, // 流式输出
  max_tokens: 8192, // 限制一次请求中模型生成 completion 的最大 token 数(默认使用 4096)
  temperature: 0.6, // 严谨采样 越低越严谨(默认1)
})

// 返回ai内容
console.log(completion.choices[0].message.content)

流式输出内容。

// 处理流式输出
let content = ''
for await (const chunk of completion) {
  content += chunk.choices[0].delta.content;
  chatState.updateSession(uniKey, content)
  if(chunk.choices[0].finish_reason == 'stop') {
    loading.value = false
  }
  if(props.reachBottom) {
    props.scrollBottom()
  }
}

基于vue3+deepseek搭建网页ai对话就分享到这里,希望对大家有些帮助~

附上几个项目实例
Electron32-MacOS:基于vue3+electron32+arcoDesign仿win/mac桌面os模板
https://segmentfault.com/a/1190000045245775
基于uniapp+vue3+uv-ui聊天实例|uni-app+vite4仿微信app应用
https://segmentfault.com/a/1190000044847552
tauri2.0+vite6客户端仿MacOS桌面|tauri2+rust+vue3桌面os
https://segmentfault.com/a/1190000045667190
tauri2.0+vue3桌面端后台Exe系统|tauri2+rust+vite5管理系统后台模板
https://segmentfault.com/a/1190000045381943
基于uniapp+vite5+pinia2跨端预订酒店app系统
https://segmentfault.com/a/1190000045556523
原创electron31+vue3+elementPlus仿微信客户端聊天Exe实例
https://segmentfault.com/a/1190000045042968
基于electron31+vue3+pinia2桌面端后台管理模板
https://segmentfault.com/a/1190000045186093


xiaoyan2017
765 声望327 粉丝

web前端开发爱好者,专注于前端h5、jquery、vue、react、angular等技术研发实战项目案例。