购物网站建设建站/福州短视频seo网红

购物网站建设建站,福州短视频seo网红,微网站建设定制网站建设,php 如何用op浏览器开发手机网站整理不易,请不要吝啬你的赞和收藏。 1. 前言 这篇文章是 Spring AI Q&A 系统的前端实现。这篇文章将介绍如何快速搭建一个基于 vue3 ElementPlus 的前端项目,vue3 项目的目录结构介绍,如何在前端实现流式响应,如何高亮显示…

整理不易,请不要吝啬你的赞和收藏。

1. 前言

这篇文章是 Spring AI Q&A 系统的前端实现。这篇文章将介绍如何快速搭建一个基于 vue3 + ElementPlus 的前端项目,vue3 项目的目录结构介绍,如何在前端实现流式响应,如何高亮显示代码等。

效果展示:

2. 前提条件

  • 后端实现:

    【Spring AI】基于SpringAI+Vue3+ElementPlus的Q&A系统实现(后端)-CSDN博客文章浏览阅读762次,点赞26次,收藏24次。这篇文章将介绍如何基于 RAG 技术,使用 SpringAI + Vue3 + ElementPlus 实现一个 Q&A 系统。本文使用 deepseek 的 DeepSeek-V3 作为聊天模型,使用阿里百炼的 text-embedding-v3 作为向量模型,使用 redis 作为向量库。(PS:近期阿里百炼也上架了 DeepSeek-V3 和 DeepSeek-R1 模型供开发者调用,如果觉得 DeepSeek 官方 AP I比较慢的话,可以去试试)。 https://blog.csdn.net/u013176571/article/details/145368559
  • 已安装 18.3 或更高版本的 Node.js ,未安装进入 官网下载 ,LTS 为长期支持版,Current 为最新功能版。

3. 快速搭建 Elemenet-Plus 项目

我这里直接使用官网的快速搭建模板 element-plus-vite-starter ,其它方式参考 Element-Plus 官网 。

3.1 项目下载

# 下载模板
git clone https://github.com/element-plus/element-plus-vite-starter.git
# 进入项目,安装依赖包
npm install

3.2 项目结构介绍

VS Code 中引入项目,项目结构如下:

项目结构介绍:

element-plus-vite-starter/
├── node_modules/            # 存放所有安装的依赖包
├── public/                  # 静态资源文件夹
│   └── favicon.svg          # 默认的站点图标
├── src/                     # 源代码文件夹
│   ├── assets/              # 静态资源(如图片、样式等)
│   ├── components/          # Vue 组件文件夹
│   ├──── layouts/           
│   ├────── BaseHeader.vue   # 顶部导航栏布局
│   ├────── BaseSide.vue     # 侧边导航栏布局
│   ├── composables/         # Vue 3 Composition API 的逻辑复用文件夹,存放 useXXX 命名的函数
│   ├── pages/               # 页面视图文件夹
│   ├── styles/              # 样式文件夹,存放全局样式 css 类
│   ├──── element/           
│   ├────── index.scss       # 全局颜色主题配置文件           
│   ├── App.vue              # 根组件
│   ├── main.js              # 项目入口文件
│   ├── components.d.ts      # 组件的类型声明文件
│   ├── env.d.ts             # 环境变量的类型声明文件
│   ├── typed-router.d.ts    # 路由的类型声明文件
│   └── types.ts             # 全局类型定义文件,用于定义 TypeScript 类型
├── .gitignore               
├── eslint.config.ts         # ESLint 配置文件,用于代码质量检查
├── index.html               # 项目入口 HTML 文件,Vite 会以此文件为模板进行开发和构建
├── babel.config.js          # Babel 配置文件(仅在 Vue CLI 项目中)
├── package-lock.json        # npm 生成的锁定文件,确保依赖版本一致
├── package.json             # 项目依赖和配置信息
├── pnpm-lock.yaml           # pnpm 生成的锁定文件,确保依赖版本一致
├── README.md                # 项目说明文档
├── tsconfig.json            # TypeScript 配置文件,定义 TypeScript 编译选项
├── uno.config.ts            # UnoCSS 配置文件,UnoCSS 是一个用于生成原子 CSS 的工具
└── vite.config.ts           # Vite 配置文件(仅在 Vite 项目中)

3.3 启动项目

执行以下命令启动:

# 启动项目
npm run dev

浏览器访问:http://localhost:5173/

4. 页面开发

这篇文章不会提供所有前端代码,我会在主要的卡点提供相应的代码节选。

4.1 .vue 文件介绍

在 Vue3 中,我们通过创建一个 .vue 格式文件来创建页面,一个 .vue 文件由以下几个部分组成:

  • template:组件的模板部分,用于定义组件的 HTML 结构。Vue 会将模板编译为渲染函数,用于生成最终的 DOM。

  • script:组件的逻辑部分,用于定义组件的数据、方法、生命周期钩子等。

  • style:组件的样式部分,用于定义组件的 CSS 样式,支持 CSS、SCSS、Sass、Less 等。

样例:

<template><div class = "m-container" ><h1 class = "m-title" >{{ title }}</h1><button @click = "handleClick" >@click 用来绑定点击事件</button></div>
</template>// lang="ts" 表示标签中的代码是用 TypeScript 编写的
<script lang="ts" setup>
import { onMounted, reactive, toRefs } from "vue";// 定义变量
const state = reactive({title: "页面1",
});
// 用于将响应式对象中的属性转换为响应式引用(ref)
const { title } = toRefs(state)/*** 页面加载事件*/
onMounted(() => {
});/*** 绑定事件*/
const handleClick = () => {// 变量赋值title.value = "页面2"
}
</script>// lang="less" 表示使用 less 语法,scoped 用来限制作用域,只对当前组件模板生效
<style lang="less" scoped>
.m-container{.m-title{            }
}
</style>

4.2 网络请求工具类

在 src 目录下创建一个 utils 文件夹,然后创建一个 api.ts 文件,用于发起网络请求。

4.2.1 代码

import axios from 'axios';
import { ElMessage } from 'element-plus';// 创建一个 axios 实例
const baseURL = 'http://127.0.0.1:8082/your_service_name';
const apiClient = axios.create({baseURL: baseURL,timeout: 200000, // 请求超时时间headers: {'Content-Type': 'application/json',},
});const err = (error) => {console.log('error', error)if (axios.isCancel(error)) {return}if (!error.response) {ElMessage.error({message: '请求超时请检查网络链接!',offset: 80,})return Promise.reject(error)}const data = error.response.dataif (!data || data.code !== 200) {ElMessage.error(data.message || "发生未知错误,请稍后再试!")}return Promise.reject(error)
}// 请求拦截器
apiClient.interceptors.request.use((config) => {// 在发送请求之前做些什么,例如添加 tokenconst token = localStorage.getItem('token'); if (token) {config.headers['Authorization'] = `Bearer ${token}`;}return config;},err
);// 响应拦截器
apiClient.interceptors.response.use((response) => {// 对响应数据做点什么return response.data;},err
);// 定义 API 请求方法
const api = {getBaseUrl() {return baseURL;},get(url, params) {return apiClient.get(url, { params });},post(url, params, config) {return apiClient.post(url, params, config);},
};
export default api;

4.2.2 如何引用?

在需要引用的页面的 script 标签中 或 .ts 文件下键入:

import api from '@/utils/api';

4.2.3 如何调用?

const param = {};
const config = {headers: {'Content-Type': 'multipart/form-data',},
};
api.post("/ai/chat/fileUploadWithRag",param).then((response) => {console.log("Response received:", response);}).catch((error) => {// 处理错误console.error("请求失败:", error);});

4.3 如何接收 SSE 响应式消息

SSE (Server-Sent Events)是一种允许服务器向客户端推送数据的技术,属于 HTML5 的一部分。它支持服务器向客户端的单向通信,客户端通过一次长连接持续接收服务器推送的数据。响应式编程(Reactive Programming)非常适合实现 SSE,因为它允许以非阻塞的方式持续推送数据,不会阻塞服务器资源。在 SpringBoot 中可以使用 Spring WebFlux 框架来实现 SSE。在 Web 端实现 SSE 通常使用 EventSource 对象。

4.3.1 代码

同样在 utils 目录下,创建一个 sse.ts 的工具类。

class SSE {private eventSource: EventSource | null = null;/*** 连接 SSE* @param url* @param onMessage * @param onError */public connect(url: string, onMessage: (event: MessageEvent) => void, onError?: (event: Event) => void): void {this.eventSource = new EventSource(url);// 监听消息事件this.eventSource.onmessage = onMessage;// 监听错误事件if (onError) {this.eventSource.onerror = onError;}}/*** 关闭 SSE 连接*/public close(): void {if (this.eventSource) {this.eventSource.close();this.eventSource = null;}}}export default SSE;

4.3.2 如何引用?

import SSE from "@/utils/sse";

4.3.3 如何调用

需要注意的是,SSE 仅支持 GET 调用。

const state = reactive({sse: new SSE(),
});
const { sse } = toRefs(state);// 接收消息的回调函数
const handleMessage = (event: MessageEvent) => {eventMessage = eventMessage.concat(event.data);
};
// 错误处理的回调函数
const handleError = (event: Event) => {stopGenerate();console.log('SSE 连接错误:', event);
};
const url = "接口地址?param1=param1&param2=param2"
sse.value.connect(url, handleMessage, handleError);

4.4 对话组件

template 中主要代码节选,通过 message.sender 的值加载用户和AI消息的样式。

<el-scrollbar ref="scrollbar" class="message-list" always @scroll="handleScroll"><div v-for="message in messages" :key="message.id" class="message-wrapper" :class="{'user-message': message.sender === 'user','bot-message': message.sender === 'bot',}"><div class="message-bubble"><div class="message-content" v-html="message.content"></div></div></div>
</el-scrollbar>

script 中主要代码节选:

// 定义一个 Message 接口
interface Message {id: number;content: string;sender: "user" | "bot";timestamp: number;
}// 定义变量
const state = reactive({messages: [] as Message[],
});
const { messages } = toRefs(state);

4.5 如何加载 Markdown 内容

由于大模型返回的流一般为 Markdown 格式,我们使用第三方库 markdown-it 来加载内容。

4.5.1 安装 markdown-it

由于我需要支持代码高亮、数学公式、流程图等,所以我安装了额外的插件来扩展 MarkdownIt 的功能。

npm install markdown-it highlight.js katex mermaid markdown-it-sub markdown-it-sup markdown-it-emoji markdown-it-task-lists markdown-it-footnote markdown-it-deflist markdown-it-abbr markdown-it-ins markdown-it-mark

4.5.2 如何使用

template 中代码节选:

<template><div class="message-content" v-html="message.content"></div>
</template>

script 中代码节选:

// 引入 markdown-it
import MarkdownIt from "markdown-it";
// 定义MarkdownIt对象
const md = new MarkdownIt();// SSE 接收消息的回调函数
const handleMessage = (event: MessageEvent) => {eventMessage = eventMessage.concat(event.data);botMessage.content = computed(() => {return md.value.render(eventMessage);});// 设置nextTick(() => {scrollToBottom();});
};

4.6 其它

4.6.1 上传组件

使用 ElementPlus 的 upload 组件。

4.6.2 使用 Alt + Enter 键换行

Input 默认的换行快捷键为 Shift + Enter,不符合我们平时的使用习惯。

const handleKeyDown = (event: KeyboardEvent) => {if (event.key === "Enter") {// 按下 Alt + Enter 键时,插入换行符if (event.altKey) {const cursorPosition = event.target.selectionStart;const textBeforeCursor = inputMessage.value.slice(0, cursorPosition);const textAfterCursor = inputMessage.value.slice(cursorPosition);inputMessage.value = textBeforeCursor + '\n' + textAfterCursor;event.target.selectionStart = cursorPosition + 1;event.target.selectionEnd = cursorPosition + 1;return;}event.preventDefault();sendMessage();}
};

4.6.3 消息自动滚动到最下方

代码节选:

 // 定义变量
const state = reactive({autoScroll: true,scrollbar: {} as any,
});
const { autoScroll, scrollbar } = toRefs(state);/*** 消息滚动事件监听*/
const handleScroll = ({ scrollTop }: { scrollTop: number }) => {const scrollHeight = scrollbar.value.wrapRef?.scrollHeight || 0;const clientHeight = scrollbar.value.wrapRef?.clientHeight || 0;autoScroll.value = scrollTop + clientHeight >= scrollHeight - 10;
};/*** 滚动到最下方*/
const scrollToBottom = () => {if (autoScroll.value) {nextTick(() => {scrollbar.value?.setScrollTop(scrollbar.value.wrapRef?.scrollHeight);});}
};

5. 参考文档

  • Vue3 文档
  • Element Plus 文档
  • markdown-it 文档

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/70130.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

企业级API集成方案:基于阿里云函数计算调用DeepSeek全解析

解决方案链接&#xff1a;https://www.aliyun.com/solution/tech-solution/deepseek-r1-for-platforms?utm_contentg_1000401616 何为DeepSeek R1 DeepSeek R1模型有诸多技术优势。高效架构设计使其能更高效提取特征&#xff0c;减少冗余计算&#xff0c;提升数据处理速度、…

K8s学习总结

文章目录 介绍Kubernetes 核心组件k8s安装环境安装组件 常用命令测试1. 创建一个测试应用程序2. 检查 Pod 是否运行 3. 暴露应用让外部访问4. 查看服务的暴露端口5. 访问 nginx 服务6. 验证节点调度 如有错误&#xff0c;敬请指针&#xff0c;谢谢! 介绍 Kubernetes&#xff0…

说下JVM中一次完整的GC流程?

大家好&#xff0c;我是锋哥。今天分享关于【说下JVM中一次完整的GC流程?】面试题。希望对大家有帮助&#xff1b; 说下JVM中一次完整的GC流程? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 JVM中的一次完整的垃圾回收&#xff08;GC&#xff09;流程可以概括为…

dnslog+sqlmap外带数据

目录 爆库 爆表 爆列 爆数据 sqlmapDNSlog 外带参数 –dns-domain参数注入 –dns-domain参数为dnslog平台的域名&#xff08;我们也可以使用本地&#xff09; 爆库 python sqlmap.py -u "http://127.0.0.1/sqli/less-8/index.php/?id1" -techniqueB -dns-dom…

提升顾客转化率:融合2+1链动模式AI智能名片与S2B2C商城小程序的创新策略

摘要&#xff1a;在数字化转型的背景下&#xff0c;零售商面临着提升顾客转化率的巨大挑战。本文旨在探讨如何通过整合顾客行为数据、21链动模式、AI智能名片及S2B2C商城小程序等新兴技术与商业模式&#xff0c;来精准定位顾客需求&#xff0c;优化营销策略&#xff0c;从而提高…

以若依移动端版为基础,实现uniapp的flowable流程管理

1.前言 此代码是若依移动端版为基础&#xff0c;实现flowable流程管理&#xff0c;支持H5、APP和微信小程序三端。其中&#xff0c;APP是在安卓在雷电模拟器环境下完成的&#xff0c;其他环境未测试&#xff0c;此文章中所提及的APP均指上述环境。移动端是需要配合若依前后端分…

细说STM32F407单片机RTC的备份寄存器原理及使用方法

目录 一、备份寄存器的功能 二、示例功能 三、项目设置 1、晶振、DEBUG、CodeGenerator、USART6 2、RTC 3、NVIC 4、GPIO 及KEYLED 四、软件设计 1、main.h 2、main.c 3、rtc.c 4、keyled.c、keyled.h 五、运行调试 本实例旨在介绍备份寄存器的作用。本实例继续使…

建筑行业安全技能竞赛流程方案

一、比赛时间&#xff1a; 6月23日8&#xff1a;30分准时到场&#xff1b;9&#xff1a;00&#xff0d;10&#xff1a;00理论考试&#xff1b;10&#xff1a;10-12:00现场隐患答疑&#xff1b;12:00-13&#xff1a;30午餐&#xff1b;下午13&#xff1a;30-15&#xff1a;30现场…

解锁机器学习核心算法 | 线性回归:机器学习的基石

在机器学习的众多算法中&#xff0c;线性回归宛如一块基石&#xff0c;看似质朴无华&#xff0c;却稳稳支撑起诸多复杂模型的架构。它是我们初涉机器学习领域时便会邂逅的算法之一&#xff0c;其原理与应用广泛渗透于各个领域。无论是预测房价走势、剖析股票市场波动&#xff0…

JAVA生产环境(IDEA)排查死锁

使用 IntelliJ IDEA 排查死锁 IntelliJ IDEA 提供了强大的工具来帮助开发者排查死锁问题。以下是具体的排查步骤&#xff1a; 1. 编写并运行代码 首先&#xff0c;我们编写一个可能导致死锁的示例代码&#xff1a; public class DeadlockExample {private static final Obj…

解决DeepSeek服务器繁忙问题

目录 解决DeepSeek服务器繁忙问题 一、用户端即时优化方案 二、高级技术方案 三、替代方案与平替工具&#xff08;最推荐简单好用&#xff09; 四、系统层建议与官方动态 用加速器本地部署DeepSeek 使用加速器本地部署DeepSeek的完整指南 一、核心原理与工具选择 二、…

机器学习 - 大数定律、可能近似正确学习理论

一、大数定律&#xff1a; 大数定律是概率论中的一个基本定理&#xff0c;其核心思想是&#xff1a;当独立重复的随机试验次数足够大时&#xff0c;样本的平均值会趋近于该随机变量的期望值。下面从直观和数学两个角度来说明这一概念&#xff1a; 1. 直观理解 重复试验的稳定…

【触想智能】工业显示器和普通显示器的区别以及工业显示器的主要应用领域分析

在现代工业中&#xff0c;工业显示器被广泛应用于各种场景&#xff0c;从监控系统到生产控制&#xff0c;它们在实时数据显示、操作界面和信息传递方面发挥着重要作用。与普通显示器相比&#xff0c;工业显示器在耐用性、可靠性和适应特殊环境的能力上有着显著的差异。 触想工业…

PyCharm2024使用Python3.12在Debug时,F8步进时如同死机状态

在使用时PyCharm2024&#xff0b;Python3.12&#xff0c;在程序进行调试时&#xff0c;按F8步进时如同死机状态。 1、相同的程序在PyCharm2023&#xff0b;Python3.9时是没有问题的&#xff0c;因此决定重装PyCharm2023&#xff0b;Python3.9&#xff0c;进行调试——调试OK。 …

LLaMA-Factory DeepSeek-R1 模型 微调基础教程

LLaMA-Factory 模型 微调基础教程 LLaMA-FactoryLLaMA-Factory 下载 AnacondaAnaconda 环境创建软硬件依赖 详情LLaMA-Factory 依赖安装CUDA 安装量化 BitsAndBytes 安装可视化微调启动 数据集准备所需工具下载使用教程所需数据合并数据集预处理 DeepSeek-R1 可视化微调数据集处…

STM32 如何使用DMA和获取ADC

目录 背景 ‌摇杆的原理 程序 端口配置 ADC 配置 DMA配置 背景 DMA是一种计算机技术&#xff0c;允许某些硬件子系统直接访问系统内存&#xff0c;而不需要中央处理器&#xff08;CPU&#xff09;的介入&#xff0c;从而减轻CPU的负担。我们可以通过DMA来从外设&#xf…

DeepSeek与医院电子病历的深度融合路径:本地化和上云差异化分析

一、引言 1.1 研究背景与意义 在医疗信息化快速发展的当下,电子病历系统已成为医院信息管理的核心构成。电子病历(EMR)系统,是指医务人员在医疗活动过程中,使用医疗机构信息系统生成的文字、符号、图标、图形、数据、影像等数字化信息,并能实现存储、管理、传输和重现的…

【kafka系列】生产者

目录 发送流程 1. 流程逻辑分析 阶段一&#xff1a;主线程处理 阶段二&#xff1a;Sender 线程异步发送 核心设计思想 2. 流程 关键点总结 重要参数 一、核心必填参数 二、可靠性相关参数 三、性能优化参数 四、高级配置 五、安全性配置&#xff08;可选&#xff0…

Docker 入门与实战:从安装到容器管理的完整指南

&#x1f680; Docker 入门与实战&#xff1a;从安装到容器管理的完整指南 &#x1f31f; &#x1f4d6; 简介 在现代软件开发中&#xff0c;容器化技术已经成为不可或缺的一部分。而 Docker 作为容器化领域的领头羊&#xff0c;以其轻量级、高效和跨平台的特性&#xff0c;深…

MySQL 插入替换语句(replace into statement)

我们日常使用 insert into 语句向表中插入数据时&#xff0c;一定遇到过主键或唯一索引冲突的情况&#xff0c;MySQL的反应是报错并停止执行后续的语句&#xff0c;而replace into语句可以实现强制插入。 文章目录 一、replace into 语句简介1.1 基本用法1.2 使用set语句 二、注…