uniapp-chatgpt跨端仿ChatGPT实例|uniapp+vue3+pinia多端聊天模板

  • uniapp-chatgpt跨端仿ChatGPT实例|uniapp+vue3+pinia多端聊天模板已关闭评论
  • 75 次浏览
  • A+
所属分类:Web前端
摘要

基于uniapp+vite4+pinia 跨多端实现chatgpt会话模板Uniapp-ChatGPT。 uni-chatgpt 使用uni-app+vite4+vue3+pinia+uview-plus 等技术构建多端仿制ChatGPT手机端APP会话应用模板。支持编译到h5+小程序+APP端 ,支持渲染markdown语法及代码高亮 、解决软键盘撑起布局 问题。

基于uniapp+vite4+pinia跨多端实现chatgpt会话模板Uniapp-ChatGPT

uni-chatgpt 使用uni-app+vite4+vue3+pinia+uview-plus等技术构建多端仿制ChatGPT手机端APP会话应用模板。支持编译到h5+小程序+APP端,支持渲染markdown语法及代码高亮、解决软键盘撑起布局问题。

◆ 效果预览

编译 [H5+小程序+App端] 效果如下

uniapp-chatgpt跨端仿ChatGPT实例|uniapp+vue3+pinia多端聊天模板

◆ 技术栈

  • 编辑器:HbuilderX 3.8.4
  • 框架技术:Uniapp+Vite4+Vue3+Pinia
  • UI组件库:uView-plus^3.1.31
  • markdown渲染:markdown-it
  • 代码高亮:highlight.js
  • 本地缓存:pinia-plugin-unistorage
  • 弹框组件:ua-popup(基于uniapp封装跨端弹层组件)
  • 自定义组件:导航条ua-navbar+菜单栏ua-tabbar
  • 支持编译:小程序+H5+APP端

uniapp-chatgpt跨端仿ChatGPT实例|uniapp+vue3+pinia多端聊天模板

◆ 功能特性

  1. 沉浸式自定义顶部导航条+底部tabbar
  2. 支持h5+小程序+App端渲染markdown语法及代码高亮
  3. 基于pinia全局状态管理
  4. 基于uview-plus跨端vue3组件库
  5. 支持会话本地缓存

uniapp-chatgpt跨端仿ChatGPT实例|uniapp+vue3+pinia多端聊天模板

uniapp-chatgpt跨端仿ChatGPT实例|uniapp+vue3+pinia多端聊天模板

◆ 项目结构目录

基于hbuilderx创建的项目,整个项目页面全部采用uniapp vue3语法编码开发。

uniapp-chatgpt跨端仿ChatGPT实例|uniapp+vue3+pinia多端聊天模板

如果对uniapp结合vue3创建多端项目感兴趣,可以去看看之前的分享文章。

https://www.cnblogs.com/xiaoyan2017/p/17487018.html

uniapp-chatgpt跨端仿ChatGPT实例|uniapp+vue3+pinia多端聊天模板

uniapp-chatgpt跨端仿ChatGPT实例|uniapp+vue3+pinia多端聊天模板

uniapp-chatgpt跨端仿ChatGPT实例|uniapp+vue3+pinia多端聊天模板

uniapp-chatgpt跨端仿ChatGPT实例|uniapp+vue3+pinia多端聊天模板

uniapp-chatgpt跨端仿ChatGPT实例|uniapp+vue3+pinia多端聊天模板

uniapp-chatgpt跨端仿ChatGPT实例|uniapp+vue3+pinia多端聊天模板

uniapp-chatgpt跨端仿ChatGPT实例|uniapp+vue3+pinia多端聊天模板

uniapp-chatgpt跨端仿ChatGPT实例|uniapp+vue3+pinia多端聊天模板

uniapp-chatgpt跨端仿ChatGPT实例|uniapp+vue3+pinia多端聊天模板

uniapp-chatgpt跨端仿ChatGPT实例|uniapp+vue3+pinia多端聊天模板

uniapp-chatgpt跨端仿ChatGPT实例|uniapp+vue3+pinia多端聊天模板

uniapp-chatgpt跨端仿ChatGPT实例|uniapp+vue3+pinia多端聊天模板

uniapp-chatgpt跨端仿ChatGPT实例|uniapp+vue3+pinia多端聊天模板

uniapp-chatgpt跨端仿ChatGPT实例|uniapp+vue3+pinia多端聊天模板

uniapp-chatgpt跨端仿ChatGPT实例|uniapp+vue3+pinia多端聊天模板

◆ Uniapp自定义多端Navbar+Tabbar组件

项目中顶部navbar和底部tabbar均是自定义组件实现功能,保证整体风格统一协调。

uniapp-chatgpt跨端仿ChatGPT实例|uniapp+vue3+pinia多端聊天模板

uniapp-chatgpt跨端仿ChatGPT实例|uniapp+vue3+pinia多端聊天模板

uniapp-chatgpt跨端仿ChatGPT实例|uniapp+vue3+pinia多端聊天模板

uniapp-chatgpt跨端仿ChatGPT实例|uniapp+vue3+pinia多端聊天模板

uniapp-chatgpt跨端仿ChatGPT实例|uniapp+vue3+pinia多端聊天模板

如下图:在components目录下新建组件。支持easycom模式,如需引入,直接使用。

uniapp-chatgpt跨端仿ChatGPT实例|uniapp+vue3+pinia多端聊天模板

<ua-navbar back="false" custom :title="title" size="40rpx" center fixed :bgcolor="bgcolor">     <template #left>         <view @click="showSidebar=true"><text class="iconfont ve-icon-menuon"></text></view>     </template>     <template #right>         <text class="iconfont ve-icon-plus fs-36" @click="handleNewChat"></text>     </template> </ua-navbar>

至于如何实现组件功能,这里就不做详细介绍了,大家可以去看看之前的分享文章。

https://www.cnblogs.com/xiaoyan2017/p/14978408.html

另外Navbar和Tabbar组件的vue2版本已经发布到了插件市场,如果大家有需要可以去下载,一次性拿走使用。

https://ext.dcloud.net.cn/plugin?id=5592
https://ext.dcloud.net.cn/plugin?id=5593

◆ 主入口main.js配置

在main.js中使用vue3语法,引入pinia状态管理、uview-plus组件库。

/**  * 主入口配置   */  import App from './App' import { createSSRApp } from 'vue'  // 引入pinia状态管理 import pinia from '@/store'  // 引入uview-plus组件库 import uviewplus from '@/uview-plus'  export function createApp() {     const app = createSSRApp(App)     app.use(pinia)     app.use(uviewplus)     return {         app,         pinia     } }

◆ App.vue模板配置

在app.vue中使用vue3 setup语法,获取手机系统状态栏高度。

<script setup>     import { provide } from 'vue'     import { onLaunch, onShow, onHide, onPageNotFound } from '@dcloudio/uni-app'          onLaunch(() => {         console.log('App Launch')                  // 隐藏tabBar         uni.hideTabBar()         // 初始化         initSysInfo()     })          onShow(() => {         console.log('App Show')     })          onHide(() => {         console.log('App Hide')     })          onPageNotFound((e) => {         console.warn('Router Error>>', ` No match path "${e.path}" `);         uni.redirectTo({             url: '/pages/404/index'         })     })          const initSysInfo = () => {         uni.getSystemInfo({             success: (e) => {                 // 获取手机状态栏高度                 let statusBar = e.statusBarHeight                 let customBar                                  // #ifndef MP                 customBar = statusBar + (e.platform == 'android' ? 50 : 45)                 // #endif                                  // #ifdef MP-WEIXIN                 // 获取胶囊按钮的布局位置信息                 let menu = wx.getMenuButtonBoundingClientRect()                 // 导航栏高度 = 胶囊下距离 + 胶囊上距离 - 状态栏高度                 customBar = menu.bottom + menu.top - statusBar                 // #endif                                  // #ifdef MP-ALIPAY                 customBar = statusBar + e.titleBarHeight                 // #endif                                  // 目前globalData在vue3 setup支持性不好,改为provide/inject方式                 provide('globalData', {                     statusBarH: statusBar,                     customBarH: customBar,                     platform: e.platform                 })             }         })     } </script>

由于底部tabbar采用自定义组件,所以在onLaunch中给隐藏掉系统tabbar功能。

uniapp-chatgpt跨端仿ChatGPT实例|uniapp+vue3+pinia多端聊天模板

如上图:在vue3 setup中globalData有兼容性问题,所以使用了provide/inject替代方案。

◆ uniapp vue3渲染markdown语法+代码高亮

uni-chatgpt能很好的兼容适配 h5+小程序+App端 解析markdown语法及代码高亮显示。

uniapp-chatgpt跨端仿ChatGPT实例|uniapp+vue3+pinia多端聊天模板

uniapp-chatgpt跨端仿ChatGPT实例|uniapp+vue3+pinia多端聊天模板

至于如何在uniapp中实现解析markdown语法模板以及解决键盘撑起页面布局问题,大家可以去看看之前的这篇文章。

https://www.cnblogs.com/xiaoyan2017/p/17502105.html

◆ uniapp多功能Input输入编辑框

为了整体风格一致,会话编辑框采用自定义组件实现功能。

uniapp-chatgpt跨端仿ChatGPT实例|uniapp+vue3+pinia多端聊天模板

uniapp-chatgpt跨端仿ChatGPT实例|uniapp+vue3+pinia多端聊天模板

目前兼容h5+小程序+App端,支持input单行文本、textarea多行文本,可自适应高度,自定义前缀/后缀插槽及密码输入等功能。

uniapp-chatgpt跨端仿ChatGPT实例|uniapp+vue3+pinia多端聊天模板

<template>     <div         class="ve__input"         :class="[             preClass,             isClass,             sizeClass,             {'is-disabled': isDisabled},             {'is-resizable': type == 'textarea' && !autosize},             {'ve__input--group': $slots.prepend || $slots.append},             {'ve__input--group__prepend': $slots.prepend},             {'ve__input--group__append': $slots.append}         ]"     >             <!-- 前置插槽(prepend slot) -->             <div v-if="$slots.prepend" class="ve__input--prepend"><slot name="prepend" /></div>              <div class="ve__input-wrapper">                 <!-- 输入框前缀 -->                 <div v-if="$slots.prefix || prefixIcon" class="ve__input--prefix">                     <span class="ve__input--prefix__inner">                         <slot name="prefix" />                         <i v-if="prefixIcon" class="iconfont" :class="prefixIcon"></i>                     </span>                 </div>                  <template v-if="type != 'textarea'">                     <input                         class="ve__input-inner"                         ref="inputRef"                         :type="showPassword ? (passwordVisible ? 'text' : 'password') : type"                         :value="modelValue"                         :name="name"                         :maxlength="maxlength"                         :readonly="readonly"                         :disabled="isDisabled"                         :placeholder="placeholder"                         :cursor-spacing="15"                         :focus="autofocus"                         @focus="handleFocus"                         @blur="handleBlur"                         @input="handleInput"                         @change="handleChange"                         @keydown="handleKeydown"                     />                 </template>                 <template v-else>                     <textarea                         class="ve__input-inner ve__textarea-inner"                         ref="textareaRef"                         :value="modelValue"                         :maxlength="maxlength"                         :readonly="readonly"                         :disabled="isDisabled"                         :placeholder="placeholder"                         :show-confirm-bar="false"                         :adjust-position="false"                         :cursor-spacing="15"                         :focus="autofocus"                         :auto-height="isTrue(autosize) || isObject(autosize)"                         :style="textareaStyle"                         @focus="handleFocus"                         @blur="handleBlur"                         @input="handleInput"                         @change="handleChange"                         @keydown="handleKeydown"                     />                 </template>                  <!-- 输入框后缀 -->                 <div v-if="showSuffixVisible" class="ve__input--suffix" @click="handleSearch" @mousedown.prevent>                     <span class="ve__input--suffix__inner">                         <!-- 后缀 -->                         <template v-if="!showClear || !showPwdVisible">                             <slot name="suffix" />                             <i v-if="suffixIcon" class="iconfont" :class="suffixIcon"></i>                         </template>                         <!-- 清除 -->                         <i v-if="showClear" class="iconfont ve-icon-close-circle ve__input-clear" @click="handleClear" @mousedown.prevent></i>                         <!-- 密码可见 -->                         <i v-if="showPwdVisible" class="iconfont ve-icon-hide ve__input-password" :class="{'ve-icon-eye1': passwordVisible}" @click="handlePwdVisible" @mousedown.prevent @mouseup.prevent></i>                         <!-- 限制字数 -->                         <em v-if="showLimitWordVisible" class="ve__input-limitword">{{inputLength}} / {{maxlength}}</em>                     </span>                 </div>             </div>              <!-- 后置插槽(append slot) -->             <div v-if="$slots.append" class="ve__input--append" @click="handleSearch" @mousedown.prevent><slot name="append" /></div>     </div> </template>

<template>     <view class="ugpt__editor">         <view class="ugpt__editor-inner flexbox">             <u-button class="btn" shape="circle" @click="handleUploadImage"><text class="iconfont ve-icon-image fs-32"></text></u-button>             <u-button class="btn" shape="circle" @click="showPopover=true"><text class="iconfont ve-icon-yuyin1 fs-32"></text></u-button>             <ua-input                 class="flex1"                 v-model="editorText"                 type="textarea"                 :autosize="{maxRows: 6}"                 clearable                 placeholder="Prompt..."                 @clear="handleClear"             />             <u-button type="success" shape="circle" :disabled="!editorText" @click="handleSubmit" style="transform: scale(.8);width: auto;"><text class="iconfont ve-icon-send-o"></text></u-button>         </view>     </view> </template>

◆ uniapp配置vite.config.js

使用hbuilderx构建的uniapp项目同样支持.env文件及vite.config.js配置。支持修改默认运行端口。

uniapp-chatgpt跨端仿ChatGPT实例|uniapp+vue3+pinia多端聊天模板

import { defineConfig, loadEnv } from 'vite' import uni from '@dcloudio/vite-plugin-uni' import { resolve } from 'path' import { parseEnv } from './utils/env'  // https://vitejs.dev/config/ export default defineConfig(({ command, mode }) => {     const viteEnv = loadEnv(mode, __dirname)     const env = parseEnv(viteEnv)      return {         plugins: [             uni()         ],                  define: {             // 自定义环境变量             'process.env.VITE_APPNAME': JSON.stringify('uniapp-chatgpt'),             'process.env.VITE_ENV': env         },          // base: '/',         // mode: 'development', // Default: 'development' for serve, 'production' for build          /*构建选项*/         esbuild: {             // 打包去除 console.log 和 debugger             drop: env.VITE_DROP_CONSOLE && command === 'build' ? ["console", "debugger"] : []         },          /*开发服务器选项*/         server: {             // 端口             port: env.VITE_PORT,             // 运行时自动打开浏览器             open: env.VITE_OPEN,             // 代理配置             proxy: {                 // ...             }         }     } })

OK,基于uniapp+vue3构建跨端仿制chatgpt模板就分享到这里,希望对大家有所帮助~~?

最后附上一个vue3+electron25桌面端实例项目

https://www.cnblogs.com/xiaoyan2017/p/17468074.html

uniapp-chatgpt跨端仿ChatGPT实例|uniapp+vue3+pinia多端聊天模板