为了账号安全,请及时绑定邮箱和手机立即绑定

【首创】vue3-wegpt 基于vite4+pinia2构建仿chatgpt聊天实例

标签:
Vue.js Sass/Less

vite4-wegpt 基于vite4.x+vue3+vue-router+pinia2模仿chatgpt聊天。

图片描述

图片描述

vue3-wegpt 基于vite4.x构建,采用vue3 setup语法编码开发。

图片描述

实现技术

  • 编辑器:cursor
  • 框架技术:vue3+vite4.x+pinia2
  • 组件库:veplus (基于vue3桌面端组件库)
  • 国际化方案:vue-i18n^9.2.2
  • 代码高亮:highlight.js^11.7.0
  • 本地存储:pinia-plugin-persistedstate^3.1.0
  • markdown解析:vue3-markdown-it
  • 样式处理:sass^1.62.0

图片描述

功能特性

  1. 编辑器:cursor
  2. 框架技术:vue3+vite4.x+pinia2
  3. 组件库:veplus (基于vue3桌面端组件库)
  4. 国际化方案:vue-i18n^9.2.2
  5. 代码高亮:highlight.js^11.7.0
  6. 本地存储:pinia-plugin-persistedstate^3.1.0
  7. markdown解析:vue3-markdown-it
  8. 样式处理:sass^1.62.0

图片描述

项目结构

图片描述

图片描述

图片描述

图片描述

图片描述

图片描述

图片描述

聊天功能

图片描述

<template>
    <div class="vegpt__editor">
        <div class="vegpt__editor-inner">
            <Flex :gap="0">
                <Popover placement="top" trigger="click" width="150">
                    <Button class="btn" type="link" icon="ve-icon-yuyin1" v-tooltip="{content: '发送语音', theme: 'light', arrow: false}"></Button>
                    <template #content>
                        <div class="flexbox flex-alignc flex-col" style="padding: 15px 0;">
                            <Icon name="ve-icon-yuyin" size="40" color="#0fa27e" />
                            <p class="fs-12 mb-15 c-999">网络不给力</p>
                            <Button size="small"><i class="dot"></i>开始讲话</Button>
                        </div>
                    </template>
                </Popover>
                <Button class="btn" type="link" v-tooltip="{content: '发送图片', theme: 'light', arrow: false}">
                    <Icon name="ve-icon-photo" size="16" cursor />
                    <input ref="uploadImgRef" type="file" title="" accept="image/*" @change="handleUploadImage" />
                </Button>
                <Input
                    class="flex1"
                    ref="editorRef"
                    v-model="editorText"
                    type="textarea"
                    :autosize="{maxRows: 4}"
                    clearable
                    placeholder="Prompt..."
                    @keydown="handleKeydown"
                    @clear="handleClear"
                    style="margin: 0 5px;"
                />
                <Button class="btn" type="link" icon="ve-icon-submit" @click="handleSubmit"></Button>
            </Flex>
        </div>
    </div>
</template>
<script setup>
    import { ref, watch } from 'vue'
    import { guid } from '@/utils'
    import { chatStore } from '@/store/modules/chat'

    const props = defineProps({
        value: { type: [String, Number] }
    })
    const emit = defineEmits(['clear'])

    const chatState = chatStore()
    
    const uploadImgRef = ref()
    const editorRef = ref()
    const editorText = ref(props.value)

    // ...

    // 发送会话
    const handleSubmit = () => {
        editorRef.value.focus()
        if(!editorText.value) return

        let data = {
            type: 'text',
            role: 'User',
            key: guid(),
            content: editorText.value
        }
        chatState.addSession(data)
        // 清空
        editorText.value = ''
    }
    const handleKeydown = (e) => {
        // ctrl+enter
        if(e.ctrlKey && e.keyCode == 13) {
            handleSubmit()
        }
    }

    // 选择图片
    const handleUploadImage = () => {
        let file = uploadImgRef.value.files[0]
        if(!file) return
        let size = Math.floor(file.size / 1024)
        console.log(size)
        if(size > 2*1024) {
            Message.danger('图片大小不能超过2M')
            uploadImgRef.value.value = ''
            return false
        }
        let reader = new FileReader()
        reader.readAsDataURL(file)
        reader.onload = function() {
            let img = this.result

            let data = {
                type: 'image',
                role: 'User',
                key: guid(),
                content: img
            }
            chatState.addSession(data)
        }
    }

    // ...
</script>

使用pinia替代vuex进行状态管理。pinia-plugin-persistedstate 本地存储。

import { createPinia } from 'pinia'
// 引入pinia本地持久化存储
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'

const pinia = createPinia()
pinia.use(piniaPluginPersistedstate)

export default pinia

OKer,以上就是vue3开发仿制chatgpt聊天的一些分享,希望对各位有点小帮助。

点击查看更多内容
1人点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
Web前端工程师
手记
粉丝
28
获赞与收藏
94

关注作者,订阅最新文章

阅读免费教程

感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消