在当今数字化时代,AI 技术正逐渐融入我们的生活。本项目将带领您使用 Vue 框架,以简洁高效的方式实现一个令人惊叹的 AI 页面。通过深入浅出的步骤和清晰的代码示例,即使您是 Vue 的初学者,也能轻松掌握其中的奥秘,为您开启通往 AI 与前端交互的精彩之旅。
开始前的准备:node环境,vue3(包含路由),tailwindcss css,chatgpt的网站以及api。 node环境可以参考这个教程:(blog.csdn.net/Nicolecocol…)
vue3的npm的安装命令:
初始化项目 npm init -y
安装 Vite npm init vite
在后续的选择中选择vue -> JavaScript
tailwindcss css的npm安装
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p
chatgpt网站: api.302.ai/v1/chat/com…
开干
所需文件及位置
**tailwind.css文件的内容
**
@tailwind base; //导入 Tailwind CSS 的基础样式,这些通常是一些重置和默认 //的样式设置,用于确保在不同浏览器中的一致性和基本的样式表现。 @tailwind components; //导入可能自定义的组件相关的样式。这部分通常用于覆盖或扩展 //Tailwind 提供的默认组件样式,或者引入您自己定义的基于 Tailwind 类的组件样式。 @tailwind utilities; //导入 Tailwind 的实用工具类,这包含了各种常见的样式类,如 //间距、字体大小、颜色、阴影等,可以直接应用于 HTML 元素来快速实现各种样式效果。
当然您也可以用原生css,这些都是指提供页面的样式
gpt.js里面的的内容
export const chat = async (messages, apiKey) => { // 定义一个名为 chat 的异步函数,接收消息数组 messages 和 API 密钥 apiKey 作为参数 try { // 尝试执行以下代码 const result = await fetch("https://api.302.ai/v1/chat/completions", { // 发送一个 fetch 请求 method: "POST", // 请求方法为 POST headers: { // 设置请求头 "Content-Type": "application/json", // 设置授权信息 Authorization: `Bearer ${apiKey}`, }, body: JSON.stringify({ // 将请求体转换为 JSON 字符串 model: "gpt-3.5-turbo", messages: messages, }), }); const data = await result.json(); // 等待将响应解析为 JSON 格式 console.log(data); // 打印响应数据 return data.choices[0].message.content; // 返回响应数据中 choices 数组的第一个元素的 message 对象的 content 属性值 } catch (err) { // 如果上述操作过程中发生错误 throw err; // 抛出错误 } };
router.js路由文件的内容:
import { createRouter, createWebHashHistory } from "vue-router"; // 从 'vue-router' 库中导入创建路由和创建哈希历史记录的方法 // 定义路由对象 const router = createRouter({ history: createWebHashHistory(), // 使用 createWebHashHistory 方法创建哈希路由的历史记录模式 routes: [ // 定义路由配置数组 { path: "/", // 根路径 name: "home", // 路由名称为 'home' component: () => import("../views/Home.vue"), // 当访问根路径时,通过动态导入加载 '../views/Home.vue' 组件 }, { path: "/about", name: "about", // 路径为 '/about',路由名称为 'about' component: () => import("../views/About.vue"), // 当访问 '/about' 路径时,通过动态导入加载 '../views/About.vue' 组件 }, ], }); export default router; // 将创建的路由对象导出,以便在其他模块中使用
APP.vue文件的内容:
APP.vue是根组件,在此的作用是
路由整合:包含 <router-view>
来展示根据路由匹配动态切换的页面内容。
<template> <div> <router-view /> </div> </template> <script setup> </script> <style scoped></style>
主角来了:
<template> <div class="flex flex-col h-screen"> <!-- 顶部导航栏 --> <div class="flex flex-nowrap fixed w-full items-baseline top-0 px-6 py-4 bg-gray-100"> <div class="text-2xl font-bold">ChatGPT</div> <div class="ml-4 text-sm text-gray-500"> 基于OpenAI的ChatGPT自然语言模型人工智能对话 </div> <div class="ml-auto px-3 py-2 text-sm cursor-pointer hover:bg-white rounded-md" @click="clickConfig()"> 设置 </div> </div> <!-- 消息显示区域 --> <div> <div class="flex flex-col mt-24 px-6 pb-8"> <div :class="`flex flex-col justify-center ${item.role == 'user'? 'items-end' : 'items-start' }`" v-for="(item, index) in messageList.slice(2)" :key="index"> <p>{{ item.role }}</p> <p class="color-gray-500 text-sm">{{ item.content }}</p> </div> </div> </div> <!-- 输入区域 --> <div class="sticky bottom-0 w-full p-6 pb-8 bg-gray-100"> <div class="mb-2 text-sm text-gray-500">请输入API KEY:</div> <div> <input v-model="messageContent" class="input flex-1" :type="isConfig? 'password' : 'text'" :placeholder="isConfig? 'k-xxxxxx' : '给ChatGPT发送消息'" @keydown.enter="sendOrSave()" /> <button class="btn ml-4" :disabled="isTalking" @click="sendOrSave()"> 保存 </button> </div> </div> </div> </template> <script setup> import { ref, onMounted } from 'vue' import { chat } from '../libs/gpt.js' // 定义消息内容的响应式变量 const messageContent = ref('') // 定义是否处于配置状态的响应式变量 const isConfig = ref('') // 定义是否正在处理中的响应式变量 const isTalking = ref(false) // 点击设置的处理函数 const clickConfig = () => { isConfig.value = true; messageContent.value = getApiKey() || ''; } // 发送或保存的处理函数 const sendOrSave = () => { if (!messageContent.value.length) return; if (isConfig.value) { // 保存 API 密钥 if (saveAPIKey(messageContent.value.trim())) { isConfig.value = false; } messageContent.value = ''; } else { // 发送消息 sendMessage() } } // 组件挂载时的处理 onMounted(() => { if (getApiKey()) { isConfig.value = false } }) // 消息列表的响应式变量 const messageList = ref([ { role:'system', content: '你是 人工智能客服,请尽可能简洁地回答问题', }, { role: 'assistant', content: `你好,我是AI语言模型,我可以提供一些常用服务和信息,例如: 1. 翻译:我可以把中文翻译成英文,英文翻译成中文,还有其他一些语言翻译,比如法语、日语、西班牙语等。 2. 咨询服务:如果你有任何问题需要咨询,例如健康、法律、投资等方面,我可以尽可能为你提供帮助。 3. 闲聊:如果你感到寂寞或无聊,我们可以聊一些有趣的话题,以减轻你的压力。 请告诉我你需要哪方面的帮助,我会根据你的需求给你提供相应的信息和建议。` } ]) // 发送消息的异步函数 const sendMessage = async () => { const message = messageContent.value.trim(); try { isTalking.value = true; messageList.value.push({ role: 'user', content: message }) const data = await chat(messageList.value, getApiKey()) messageList.value.push({ role: 'assistant', content: data }) messageContent.value = '' } catch (e) { } finally { isTalking.value = false } isTalking.value = true; } // 保存 API 密钥的函数 const saveAPIKey = (apiKey) => { localStorage.setItem("apiKey", apiKey); return true; } // 获取 API 密钥的函数 const getApiKey = () => { return localStorage.getItem("apiKey"); } </script> <style scoped></style>
这段代码是一个 Vue 组件的模板和脚本部分:
模板中包含顶部导航栏、消息显示区域和输入区域。
导航栏显示应用名称和描述,并提供了“设置”按钮。
消息显示区域根据消息的发送者角色(用户或助手)进行布局显示。
输入区域用于输入消息或 API 密钥,并包含保存或发送的操作按钮。
脚本部分使用
ref
定义了一些响应式变量,如messageContent
、isConfig
、isTalking
和messageList
。messageContent
用于存储输入的消息或 API 密钥。isConfig
表示是否处于配置 API 密钥的状态。isTalking
表示是否正在处理发送或接收消息。messageList
存储了消息的角色和内容。定义了多个函数来处理不同的操作,如
clickConfig
处理设置按钮的点击,sendOrSave
处理发送或保存的操作,sendMessage
实际发送消息并处理响应,saveAPIKey
保存 API 密钥到本地存储,getApiKey
从本地存储获取 API 密钥。
例如,当用户点击“设置”按钮时,isConfig
变为 true
,输入框变为密码输入模式,并显示已保存的 API 密钥(如果有)。当用户输入消息并按下回车键或点击“保存”按钮时,根据 isConfig
的状态进行保存 API 密钥或发送消息的操作。在发送消息时,会将用户输入添加到 messageList
中,等待服务器响应并将响应内容也添加到 messageList
中。