第281集:Vue 3 ChatGPT API集成
概述
在当今前端开发领域,AI 技术的应用正在改变传统的开发模式。ChatGPT 作为一种强大的语言模型,不仅可以用于构建智能对话界面,还可以作为开发助手提升编码效率。本集将详细介绍如何在 Vue 3 项目中集成 ChatGPT API,实现智能对话功能和 AI 辅助开发工具。
ChatGPT API 集成的核心价值
- 智能对话界面:为应用添加自然语言交互能力,提升用户体验
- AI 辅助开发:利用 ChatGPT 生成代码、解答技术问题,提高开发效率
- 内容生成:自动生成文章、评论、产品描述等内容
- 智能客服:构建 24/7 在线客服系统,减轻人工负担
- 个性化推荐:基于用户输入提供智能推荐
应用场景
- 开发者工具:代码生成、错误排查、技术文档撰写
- 客户服务:智能问答、问题分流、自动回复
- 内容平台:文章生成、摘要提取、评论分析
- 教育应用:智能辅导、习题生成、学习路径规划
- 个人助手:日程安排、信息查询、任务提醒
准备工作
1. 获取 OpenAI API 密钥
要使用 ChatGPT API,首先需要获取 OpenAI API 密钥:
- 访问 OpenAI 官网
- 注册或登录账号
- 进入 "API Keys" 页面
- 创建新的 API 密钥并保存
2. 项目初始化
创建一个 Vue 3 + TypeScript 项目:
npm create vite@latest vue-chatgpt-demo -- --template vue-ts
cd vue-chatgpt-demo
npm install3. 安装必要依赖
# 安装 axios 用于 API 调用
npm install axios
# 安装环境变量管理工具
npm install dotenv
# 安装 TypeScript 类型定义
npm install --save-dev @types/node4. 配置环境变量
在项目根目录创建 .env 文件:
# .env
VITE_OPENAI_API_KEY=your_api_key_here
VITE_OPENAI_API_URL=https://api.openai.com/v1核心实现
1. API 调用封装
创建一个专门的服务文件来封装 OpenAI API 调用:
// src/services/openai.ts
import axios from 'axios';
const API_KEY = import.meta.env.VITE_OPENAI_API_KEY;
const API_URL = import.meta.env.VITE_OPENAI_API_URL;
const openaiClient = axios.create({
baseURL: API_URL,
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${API_KEY}`
}
});
interface ChatMessage {
role: 'system' | 'user' | 'assistant';
content: string;
}
interface ChatCompletionRequest {
model: string;
messages: ChatMessage[];
temperature?: number;
max_tokens?: number;
top_p?: number;
frequency_penalty?: number;
presence_penalty?: number;
}
interface ChatCompletionResponse {
id: string;
object: string;
created: number;
model: string;
choices: {
index: number;
message: ChatMessage;
finish_reason: string;
}[];
usage: {
prompt_tokens: number;
completion_tokens: number;
total_tokens: number;
};
}
export const openaiService = {
async getChatCompletion(request: ChatCompletionRequest): Promise<string> {
try {
const response = await openaiClient.post<ChatCompletionResponse>('/chat/completions', request);
return response.data.choices[0].message.content;
} catch (error) {
console.error('Error calling OpenAI API:', error);
throw error;
}
}
};2. 智能对话组件
创建一个智能对话组件:
<!-- src/components/ChatGPTComponent.vue -->
<template>
<div class="chat-container">
<div class="chat-messages">
<div
v-for="(message, index) in messages"
:key="index"
:class="['message', message.role]"
>
<div class="message-role">{{ message.role === 'user' ? 'You' : 'ChatGPT' }}</div>
<div class="message-content">{{ message.content }}</div>
</div>
<div v-if="loading" class="message assistant">
<div class="message-role">ChatGPT</div>
<div class="message-content loading">Thinking...</div>
</div>
</div>
<div class="chat-input">
<input
v-model="inputMessage"
type="text"
placeholder="Type your message..."
@keyup.enter="sendMessage"
/>
<button @click="sendMessage" :disabled="loading">Send</button>
</div>
</div>
</template>
<script setup lang="ts">
import { ref, reactive } from 'vue';
import { openaiService } from '../services/openai';
interface ChatMessage {
role: 'system' | 'user' | 'assistant';
content: string;
}
const messages = reactive<ChatMessage[]>([
{
role: 'system',
content: 'You are a helpful assistant built with Vue 3 and ChatGPT API.'
}
]);
const inputMessage = ref('');
const loading = ref(false);
const sendMessage = async () => {
if (!inputMessage.value.trim() || loading.value) return;
// Add user message
messages.push({
role: 'user',
content: inputMessage.value
});
const userMessage = inputMessage.value;
inputMessage.value = '';
loading.value = true;
try {
// Call OpenAI API
const response = await openaiService.getChatCompletion({
model: 'gpt-3.5-turbo',
messages: messages,
temperature: 0.7,
max_tokens: 1000
});
// Add assistant message
messages.push({
role: 'assistant',
content: response
});
} catch (error) {
console.error('Error sending message:', error);
messages.push({
role: 'assistant',
content: 'Sorry, there was an error processing your request.'
});
} finally {
loading.value = false;
}
};
</script>
<style scoped>
.chat-container {
width: 100%;
max-width: 800px;
margin: 0 auto;
border: 1px solid #e0e0e0;
border-radius: 8px;
overflow: hidden;
}
.chat-messages {
height: 500px;
overflow-y: auto;
padding: 20px;
background-color: #f5f5f5;
}
.message {
margin-bottom: 16px;
padding: 12px;
border-radius: 8px;
}
.message.user {
background-color: #e3f2fd;
align-self: flex-end;
}
.message.assistant {
background-color: #ffffff;
align-self: flex-start;
}
.message-role {
font-weight: bold;
margin-bottom: 4px;
font-size: 12px;
color: #666;
}
.message-content {
font-size: 14px;
line-height: 1.4;
}
.message-content.loading {
font-style: italic;
color: #999;
}
.chat-input {
display: flex;
padding: 16px;
background-color: #ffffff;
border-top: 1px solid #e0e0e0;
}
.chat-input input {
flex: 1;
padding: 12px;
border: 1px solid #e0e0e0;
border-radius: 4px;
margin-right: 8px;
}
.chat-input button {
padding: 12px 24px;
background-color: #1976d2;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
.chat-input button:hover {
background-color: #1565c0;
}
.chat-input button:disabled {
background-color: #bdbdbd;
cursor: not-allowed;
}
</style>3. AI 辅助开发工具
创建一个 AI 辅助开发工具组件:
<!-- src/components/AIDevAssistant.vue -->
<template>
<div class="ai-dev-assistant">
<h3>AI Development Assistant</h3>
<div class="tool-section">
<h4>Code Generator</h4>
<textarea
v-model="codePrompt"
placeholder="Describe the code you need..."
rows="4"
></textarea>
<button @click="generateCode" :disabled="loading">Generate Code</button>
</div>
<div v-if="generatedCode" class="code-result">
<h4>Generated Code</h4>
<pre><code>{{ generatedCode }}</code></pre>
<button @click="copyCode">Copy Code</button>
</div>
<div class="tool-section">
<h4>Bug Fixer</h4>
<textarea
v-model="bugCode"
placeholder="Paste your buggy code here..."
rows="4"
></textarea>
<button @click="fixBug" :disabled="loading">Fix Bug</button>
</div>
<div v-if="fixedCode" class="code-result">
<h4>Fixed Code</h4>
<pre><code>{{ fixedCode }}</code></pre>
<button @click="copyFixedCode">Copy Code</button>
</div>
<div v-if="loading" class="loading-indicator">
Processing...
</div>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { openaiService } from '../services/openai';
const codePrompt = ref('');
const generatedCode = ref('');
const bugCode = ref('');
const fixedCode = ref('');
const loading = ref(false);
const generateCode = async () => {
if (!codePrompt.value.trim() || loading.value) return;
loading.value = true;
try {
const response = await openaiService.getChatCompletion({
model: 'gpt-3.5-turbo',
messages: [
{
role: 'system',
content: 'You are a skilled Vue 3 developer. Generate clean, efficient, and well-commented code based on the user\'s request.'
},
{
role: 'user',
content: codePrompt.value
}
],
temperature: 0.7,
max_tokens: 1000
});
generatedCode.value = response;
} catch (error) {
console.error('Error generating code:', error);
} finally {
loading.value = false;
}
};
const fixBug = async () => {
if (!bugCode.value.trim() || loading.value) return;
loading.value = true;
try {
const response = await openaiService.getChatCompletion({
model: 'gpt-3.5-turbo',
messages: [
{
role: 'system',
content: 'You are a skilled Vue 3 developer. Find and fix bugs in the provided code. Explain the issue and provide the corrected code.'
},
{
role: 'user',
content: bugCode.value
}
],
temperature: 0.7,
max_tokens: 1000
});
fixedCode.value = response;
} catch (error) {
console.error('Error fixing bug:', error);
} finally {
loading.value = false;
}
};
const copyCode = () => {
navigator.clipboard.writeText(generatedCode.value);
alert('Code copied to clipboard!');
};
const copyFixedCode = () => {
navigator.clipboard.writeText(fixedCode.value);
alert('Code copied to clipboard!');
};
</script>
<style scoped>
.ai-dev-assistant {
max-width: 800px;
margin: 0 auto;
padding: 20px;
}
h3 {
margin-bottom: 20px;
color: #333;
}
h4 {
margin-bottom: 10px;
color: #555;
}
.tool-section {
margin-bottom: 30px;
padding: 16px;
border: 1px solid #e0e0e0;
border-radius: 8px;
background-color: #f9f9f9;
}
textarea {
width: 100%;
padding: 12px;
border: 1px solid #e0e0e0;
border-radius: 4px;
margin-bottom: 12px;
font-family: monospace;
font-size: 14px;
}
button {
padding: 8px 16px;
background-color: #4caf50;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 14px;
}
button:hover {
background-color: #45a049;
}
button:disabled {
background-color: #bdbdbd;
cursor: not-allowed;
}
.code-result {
margin-top: 20px;
padding: 16px;
border: 1px solid #e0e0e0;
border-radius: 8px;
background-color: #f5f5f5;
}
pre {
background-color: #f0f0f0;
padding: 12px;
border-radius: 4px;
overflow-x: auto;
margin-bottom: 12px;
}
code {
font-family: monospace;
font-size: 14px;
}
.loading-indicator {
margin-top: 16px;
padding: 12px;
background-color: #e3f2fd;
border: 1px solid #bbdefb;
border-radius: 4px;
color: #1976d2;
text-align: center;
}
</style>实战案例:智能客服系统
1. 项目结构
vue-chatgpt-demo/
├── src/
│ ├── components/
│ │ ├── ChatGPTComponent.vue
│ │ └── AIDevAssistant.vue
│ ├── services/
│ │ └── openai.ts
│ ├── views/
│ │ ├── ChatView.vue
│ │ └── DevAssistantView.vue
│ ├── router/
│ │ └── index.ts
│ ├── App.vue
│ └── main.ts
├── public/
├── .env
├── package.json
└── vite.config.ts2. 路由配置
// src/router/index.ts
import { createRouter, createWebHistory } from 'vue-router';
import ChatView from '../views/ChatView.vue';
import DevAssistantView from '../views/DevAssistantView.vue';
const routes = [
{
path: '/',
name: 'Chat',
component: ChatView
},
{
path: '/dev-assistant',
name: 'DevAssistant',
component: DevAssistantView
}
];
const router = createRouter({
history: createWebHistory(),
routes
});
export default router;3. 视图组件
<!-- src/views/ChatView.vue -->
<template>
<div class="view-container">
<h2>ChatGPT Chat Interface</h2>
<ChatGPTComponent />
</div>
</template>
<script setup lang="ts">
import ChatGPTComponent from '../components/ChatGPTComponent.vue';
</script>
<style scoped>
.view-container {
max-width: 1000px;
margin: 0 auto;
padding: 20px;
}
h2 {
margin-bottom: 30px;
color: #333;
}
</style><!-- src/views/DevAssistantView.vue -->
<template>
<div class="view-container">
<h2>AI Development Assistant</h2>
<AIDevAssistant />
</div>
</template>
<script setup lang="ts">
import AIDevAssistant from '../components/AIDevAssistant.vue';
</script>
<style scoped>
.view-container {
max-width: 1000px;
margin: 0 auto;
padding: 20px;
}
h2 {
margin-bottom: 30px;
color: #333;
}
</style>4. 主应用配置
<!-- src/App.vue -->
<template>
<div class="app">
<header class="app-header">
<h1>Vue 3 ChatGPT Integration</h1>
<nav>
<router-link to="/">Chat</router-link>
<router-link to="/dev-assistant">Dev Assistant</router-link>
</nav>
</header>
<main>
<router-view />
</main>
</div>
</template>
<script setup lang="ts">
// App component
</script>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: Arial, sans-serif;
line-height: 1.6;
color: #333;
}
.app {
min-height: 100vh;
display: flex;
flex-direction: column;
}
.app-header {
background-color: #1976d2;
color: white;
padding: 20px;
display: flex;
justify-content: space-between;
align-items: center;
}
.app-header h1 {
font-size: 24px;
}
nav {
display: flex;
gap: 20px;
}
nav a {
color: white;
text-decoration: none;
font-weight: bold;
}
nav a:hover {
text-decoration: underline;
}
main {
flex: 1;
padding: 20px;
}
</style>// src/main.ts
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
createApp(App).use(router).mount('#app')最佳实践
1. 性能优化
- 请求节流:限制 API 调用频率,避免过多请求
- 缓存机制:缓存常见问题的响应
- 流式响应:使用 SSE 或 WebSocket 实现流式响应,提升用户体验
- 前端状态管理:合理使用 Pinia 或 Vuex 管理对话状态
2. 错误处理
- API 错误捕获:妥善处理 API 调用失败的情况
- 网络错误处理:处理网络中断、超时等问题
- Rate Limit 处理:处理 API 速率限制
- 友好的错误提示:向用户显示清晰的错误信息
3. 安全性
- API 密钥保护:不要在前端代码中硬编码 API 密钥
- 环境变量管理:使用 .env 文件和 Vite 的环境变量机制
- 输入验证:验证用户输入,防止恶意请求
- 请求限流:在服务端实现请求限流,防止滥用
- 数据加密:对敏感数据进行加密传输
4. 用户体验
- 加载状态:显示清晰的加载状态
- 错误提示:提供友好的错误提示
- 消息格式化:美化消息显示,支持 Markdown 格式
- 历史记录:保存对话历史,支持上下文理解
- 响应时间优化:通过缓存和预加载提升响应速度
高级功能
1. 多模型支持
// 支持不同的 OpenAI 模型
export const openaiService = {
async getChatCompletion(request: ChatCompletionRequest): Promise<string> {
try {
const response = await openaiClient.post<ChatCompletionResponse>('/chat/completions', {
...request,
model: request.model || 'gpt-3.5-turbo' // 默认模型
});
return response.data.choices[0].message.content;
} catch (error) {
console.error('Error calling OpenAI API:', error);
throw error;
}
}
};2. 函数调用能力
// 支持函数调用
interface FunctionCall {
name: string;
arguments: string;
}
interface ChatCompletionRequestWithFunctions extends ChatCompletionRequest {
functions?: Array<{
name: string;
description: string;
parameters: Record<string, any>;
}>;
function_call?: 'none' | 'auto' | { name: string };
}3. 语音交互
集成 Web Speech API 实现语音输入和输出:
<!-- 语音输入功能 -->
<button @click="startVoiceInput">
<span v-if="!isListening">Start Voice</span>
<span v-else>Listening...</span>
</button>总结
本集详细介绍了如何在 Vue 3 项目中集成 ChatGPT API,包括:
- 准备工作:获取 OpenAI API 密钥、项目初始化、依赖安装
- 核心实现:API 调用封装、智能对话组件、AI 辅助开发工具
- 实战案例:智能客服系统的完整实现
- 最佳实践:性能优化、错误处理、安全性、用户体验
- 高级功能:多模型支持、函数调用能力、语音交互
通过集成 ChatGPT API,我们可以为 Vue 3 应用添加智能对话能力,构建 AI 辅助开发工具,提升开发效率和用户体验。随着 AI 技术的不断发展,这种集成方式将为前端开发带来更多可能性。
后续学习建议
- 第282集:智能代码提示
- 第283集:AI辅助代码生成
- 第284集:自然语言查询数据
- 第285集:智能表单验证
这些内容将进一步探索 Vue 3 与 AI 技术的结合,帮助你构建更加智能、高效的前端应用。