基于uniapp+vue3+deepseek+markdown搭建app版流式输出AI模板

3,657 阅读2分钟

继一个月之前分享了一篇vue3.5 + deepseek搭建网页web版流式ai对话助手,受到了很多掘友们的喜欢~ 今天带来最新研发的uni-app + deepseek-v3实战跨多端(小程序+H5+App端)流式输出AI模板。

vue3.5+deepseek+arco+markdown搭建web版流式输出AI模板

未标题-11.png

uniapp-vue3-deepseek跨端流式打字输出效果,支持亮色+暗黑主题。

p1.gif

运用技术

  • 编辑器:HbuilderX4.57
  • 技术框架:uni-app+vue3+pinia2+vite5
  • 大模型框架:deepseek-v3
  • UI组件库:uni-ui+uv-ui
  • 高亮插件:highlight.js
  • markdown组件:ua-markdown
  • 缓存组件:pinia-plugin-unistorage
  • 支持编译:H5+小程序+APP端

p2-2.gif

p3.gif

项目框架结构

整个项目采用uni-app+vue3搭建模板,对接deepseek api实现流式输出效果。

360截图20250428120235208.png

001360截图20250428091525958.png

001360截图20250428092113714.png

002360截图20250428092139934.png

002360截图20250428092506289.png

002360截图20250428092548023.png

002360截图20250428092604495.png

002360截图20250428092701512.png

003360截图20250428093154679.png

003360截图20250428093558207.png

uni-deepseek编译到h5端,支持以750px宽度显示页面布局。

018360截图20250427233454148.png

018360截图20250427233654819.png

019360截图20250427233822258.png

019360截图20250427234043289.png

022360截图20250427234932808.png

uniapp自定义环境变量.env

在项目根目录下新建一个.env配置文件。

24112456b3805c692e370f295d7345b0_1289798-20250429123238198-208491377.png

去deepseek官网申请一个key,替换掉.env文件里的key,即可畅快的体验deepseek聊天对话功能。

# 项目名称
VITE_APPNAME = 'Uniapp-DeepSeek'

# 运行端口
VITE_PORT = 5173

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

uni-app+vue3入口文件

import App from './App'
import { createSSRApp } from 'vue'

// 引入pinia状态管理
import pinia from '@/pinia'

export function createApp() {
    const app = createSSRApp(App)
    app.use(pinia)
    return {
        app,
        pinia
    }
}

未标题-2.png

未标题-6.png

项目布局模板

2eb609f0920c9a3d5842360719e6bad2_1289798-20250429123918114-670451265.png

如上图:项目整体分为自定义顶部导航+主内容区+底部编辑框区三个部分。

image.png

<template>
    <uv3-layout>
        <!-- 导航栏 -->
        <template #header>
            <Toolbar :title="chatSession?.title" />
        </template>
        
        <view v-if="chatSession && !isEmpty(chatSession.data)" class="vu__chatview flexbox flex-col">
            <scroll-view :scroll-into-view="scrollIntoView" scroll-y="true" @scrolltolower="onScrollToLower" @scroll="onScroll" style="height: 100%;">
                <view class="vu__chatbot">
                    ...
                </view>
                <view id="scrollbottom-placeholder" style="height: 1px;"></view>
            </scroll-view>
            <!-- 滚动到底部 -->
            <view class="vu__scrollbottom" @click="scrollToBottom"><text class="iconfont ai-arrD fw-700"></text></view>
        </view>
        <!-- 欢迎信息 -->
        <view v-else class="vu__welcomeinfo">
            <view class="intro flex-c flex-col">
                <view class="logo flex-c" style="gap: 15px;">
                    <view class="iconfont ai-deepseek" style="font-size: 40px;"></view>
                    <text style="color: #999; font-size: 20px;">+</text>
                    <image src="/static/uni.png" mode="widthFix" style="height: 30px; width: 30px;" />
                </view>
                <view class="name"><text class="txt text-gradient">嘿~ Uniapp-DeepSeek</text></view>
                <view class="desc">我可以帮你写代码、答疑解惑、写作各种创意内容,请把你的任务交给我吧~</view>
            </view>
            <view class="prompt">
                <view class="tip flex-c"><text class="flex1">试试这样问</text><view class="flex-c" @click="refreshPrompt">换一换<uni-icons type="refreshempty" color="#999" size="14" /></view></view>
                <view v-for="(item,index) in promptList" :key="index">
                    <view class="option" @click="changePrompt(item.prompt)">{{item.emoji}} {{item.prompt}} <text class="arrow iconfont ai-arrR c-999"></text></view>
                </view>
            </view>
        </view>
        
        <template #footer>
            <view :style="{'padding-bottom': keyboardHeight + 'px'}">
                <ChatEditor ref="editorRef" v-model="promptValue" :scrollBottom="scrollToBottom" />
            </view>
        </template>
    </uv3-layout>
</template>

p2-3.gif

uniapp解析流式返回markdown

之前有封装一个uniapp+vue3解析markdown组件,这次在之前的基础上做了一些兼容性优化。支持在H5端+小程序端+App端流式Markdown解析。

image.png

支持性:

  • 支持代码块横向滚动
  • 支持显示代码行号(关闭提升性能)
  • 支持代码复制功能(h5/app端)
  • 支持图片渲染宽度100%
  • 支持图片预览功能(h5/app端)
  • 支持链接跳转功能(h5/app端)

360截图20250428102859357.png

p2-4.gif

006360截图20250427223412312.png

007360截图20250427223910742.png

008360截图20250427224330335.png

010360截图20250427225200356.png

010360截图20250427225337615.png

012360截图20250427230434133.png

013360截图20250427232325355.png

015360截图20250427232513338.png

020360截图20250427234147313.png

022360截图20250427235024991.png

uni-app集成deepseek实现流式stream输出

由于uniapp开发三端特殊性,在小程序和app端实现流式有些差异。

经过一番捣鼓,最后选择在小程序端使用uni.request实现流式功能,在h5和app端采用renderjs实现流式。

小程序端流式

// #ifdef MP-WEIXIN
try {
    this.loading = true
    
    const requestTask = await uni.request({
        url: baseURL+'/v1/chat/completions',
        method: 'POST',
        header: {
            "Content-Type": "application/json",
            "Authorization": `Bearer ${apiKEY}`,
        },
        data: {
            // 多轮会话
            messages: this.multiConversation ? this.historySession : [{role: 'user', content: editorValue}],
            model: 'deepseek-chat', // deepseek-chat对话模型 deepseek-reasoner推理模型
            stream: true, // 流式输出
            max_tokens: 8192, // 限制一次请求中模型生成 completion 的最大 token 数(默认使用 4096)
            temperature: 0.4, // 严谨采样 越低越严谨(默认1)
        },
        enableChunked: true, //开启分块传输 transfer-encoding chunked
        success: (res) => {
            console.log('request success', res)
        },
        fail: (error) => {
            console.log('request fail', error)
            // ...
        }
    })
    requestTask.onChunkReceived((res) => {
        // console.log('Received chunk', res)
        
        const uint8Array = new Uint8Array(res.data)
        let text = String.fromCharCode.apply(null, uint8Array)
        const buffer = decodeURIComponent(escape(text))
        
        this.parseBuffer(buffer)
    })
} catch (error) {
    this.loading = false
    this.chatState.updateSession(this.botKey, {loading: false})
    throw new Error(`request error: ${error.message || '请求异常'}`)
}
// #endif

需要开启enableChunked: true分块传输。通过onChunkReceived接收流式返回。

H5和APP端调用renderjs里的fetch

// #ifdef APP-PLUS || H5
this.fetchAppH5({
    url: baseURL+'/v1/chat/completions',
    method: 'POST',
    headers: {
        "Content-Type": "application/json",
        "Authorization": `Bearer ${apiKEY}`,
    },
    body: {
        // 多轮会话
        messages: this.multiConversation ? this.historySession : [{role: 'user', content: editorValue}],
        model: 'deepseek-chat', // deepseek-chat对话模型 deepseek-reasoner推理模型
        stream: true, // 流式输出
        max_tokens: 8192, // 限制一次请求中模型生成 completion 的最大 token 数(默认使用 4096)
        temperature: 0.4, // 严谨采样 越低越严谨(默认1)
    }
})
// #endif

整个项目涉及到的知识点还是蛮多的,希望以上分享对大家有所帮助哈~ 开发不易,感谢阅读与支持!

基于electron35+DeepSeek+Vite6+Markdown实战桌面端AI流式聊天模板

vue3.5+deepseek+arco+markdown搭建web版流式输出AI模板

vue3.5+vant4+deepseek搭建mobile版流式ai对话

自研tauri2.0+vite5+vue3+element-plus电脑版exe聊天系统Vue3-Tauri2Chat

Flutter3.x深度融合短视频+直播+聊天app实例|flutter3仿抖音app商城

uni-vue3-wechat:基于uni-app+vue3+pinia2多端仿微信App聊天

自创uniapp+vue3+uvui酒店预订app系统模板|uni-app仿携程app预约酒店

Vue3-Electron32-OS桌面os实例|electron32+vite5+arco实战os桌面

duitang.gif