当前位置: 首页 > article >正文

Vue.js前端项目集成AI:SmallThinker-3B-Preview实现智能表单与对话

Vue.js前端项目集成AISmallThinker-3B-Preview实现智能表单与对话1. 引言当Vue.js遇见AI你有没有遇到过这样的场景用户填写一个复杂的表单面对几十个选项不知所措或者客服系统里用户问了一个稍微复杂点的问题机器人就答非所问。传统的Web应用交互是固定的、被动的用户只能按照开发者预设的路径走。但现在不一样了。AI大模型的出现让我们能给前端应用装上“大脑”。想象一下你的表单能理解用户意图动态调整选项你的对话框能进行有逻辑、有上下文的真实对话。这不再是科幻电影里的情节而是我们今天就能用代码实现的功能。SmallThinker-3B-Preview就是一个非常适合集成到前端项目中的轻量级AI模型。它能力均衡响应速度快对硬件要求相对友好通过标准的API就能调用。而Vue.js凭借其响应式数据绑定和组件化开发的特性是构建这类动态、智能交互界面的绝佳搭档。这篇文章我就带你一起把一个传统的Vue.js项目升级成一个能“思考”、能“对话”的智能应用。我们会从最基础的API调用开始一步步构建出智能表单和对话界面让你亲眼看到AI是如何让前端体验发生质变的。2. 项目准备与环境搭建在开始写代码之前我们需要把“舞台”搭好。这里假设你已经有一个可以运行SmallThinker-3B-Preview模型的API服务。这个服务可以是你自己在服务器上部署的也可以是云服务商提供的。关键是我们有一个可以发送HTTP请求的端点Endpoint。2.1 创建Vue.js项目如果你还没有现成的项目我们可以用Vue CLI快速创建一个。打开终端执行以下命令npm create vuelatest my-smart-ai-app创建过程中你可以根据需求选择需要的特性比如TypeScript、Router、Pinia等。为了演示清晰我们这里先创建一个基础项目。进入项目目录并安装依赖cd my-smart-ai-app npm install2.2 安装必要的依赖我们的智能应用主要需要两个额外的库一个用于优雅地发送HTTP请求另一个用于处理可能较长的AI响应流。npm install axiosaxios是一个广泛使用的HTTP客户端用起来比原生的fetch更方便功能也更全。如果你的AI接口支持流式响应比如Server-Sent Events你可能还需要考虑相关的流处理库但为了入门简单我们先从普通的请求-响应模式开始。2.3 配置API基础信息在src目录下我们创建一个services文件夹并在里面新建一个api.js文件。这个文件将集中管理所有与AI API相关的配置和基础请求函数。// src/services/api.js import axios from axios; // 配置你的AI API基础URL // 注意这里请替换成你实际可用的API地址 const AI_API_BASE_URL http://your-ai-server-address:port/v1; // 创建axios实例方便统一配置 const aiApiClient axios.create({ baseURL: AI_API_BASE_URL, timeout: 30000, // 设置一个较长的超时时间因为AI生成可能需要时间 headers: { Content-Type: application/json, // 如果需要认证可以在这里添加Authorization头 // Authorization: Bearer YOUR_API_KEY } }); /** * 调用SmallThinker-3B-Preview的聊天补全接口 * param {Array} messages - 对话消息历史格式[{role: user, content: 你好}] * param {Object} options - 其他生成参数如temperature, max_tokens等 * returns {Promise} - 返回API响应Promise */ export async function chatCompletion(messages, options {}) { const defaultOptions { model: smallthinker-3b-preview, // 指定模型 messages: messages, temperature: 0.7, // 控制创造性0-1越高越随机 max_tokens: 500, // 限制生成的最大长度 ...options // 允许覆盖默认选项 }; try { // 假设你的API端点路径是 /chat/completions const response await aiApiClient.post(/chat/completions, defaultOptions); return response.data; } catch (error) { console.error(调用AI API失败:, error); // 这里可以处理更细致的错误如网络错误、API错误等 throw error; } } export default aiApiClient;这个服务模块是我们后面所有智能功能的基石。好了环境准备就绪接下来让我们进入正题看看怎么让表单“活”起来。3. 实战一构建智能动态表单传统表单是静态的所有字段一开始就定死了。智能表单的核心思想是“根据已知信息推断未知选项”。比如用户先选择了“电子产品”作为品类那么接下来的“品牌”下拉框里就应该只出现“苹果”、“华为”、“小米”等电子品牌而不是“康师傅”或“海尔”。我们将创建一个SmartForm组件它能够根据用户已填写的内容实时调用AI来分析并建议或生成后续的表单字段。3.1 创建智能表单组件在src/components目录下创建SmartForm.vue。template div classsmart-form h3智能产品信息收集表/h3 form submit.preventhandleSubmit !-- 基础字段产品类型 -- div classform-group label forproductType你想了解或登记什么类型的产品 */label input typetext idproductType v-modelformData.productType inputdebouncedAnalyzeForm placeholder例如智能手机、笔记本电脑、护肤品... required / p classhint请尽量具体描述AI会根据你的输入推荐相关属性。/p /div !-- 动态生成的字段区域 -- div v-ifdynamicFields.length 0 classdynamic-section h4AI为您推荐的相关属性/h4 div v-forfield in dynamicFields :keyfield.key classform-group label :forfield.key{{ field.label }} span v-iffield.required*/span/label !-- 根据字段类型渲染不同的输入组件 -- input v-iffield.type text :typefield.type :idfield.key v-modelformData[field.key] :placeholderfield.placeholder :requiredfield.required / select v-else-iffield.type select :idfield.key v-modelformData[field.key] :requiredfield.required option value disabled请选择/option option v-foroption in field.options :keyoption :valueoption {{ option }} /option /select textarea v-else-iffield.type textarea :idfield.key v-modelformData[field.key] :placeholderfield.placeholder :rowsfield.rows || 3 :requiredfield.required /textarea p classfield-hint v-iffield.hint{{ field.hint }}/p /div /div !-- 固定提交按钮 -- div classform-group button typesubmit :disabledisSubmitting {{ isSubmitting ? 提交中... : 提交信息 }} /button button typebutton clickresetForm classsecondary重置/button /div /form !-- AI思考状态提示 -- div v-ifisAnalyzing classai-thinking p AI正在分析您的输入为您推荐合适的字段.../p /div !-- 调试信息开发时可查看 -- details v-ifdebugInfo classdebug-info summary调试信息/summary pre{{ debugInfo }}/pre /details /div /template script setup import { ref, reactive, watch } from vue; import { chatCompletion } from /services/api.js; import _ from lodash; // 需要先安装 lodash: npm install lodash // 表单基础数据 const formData reactive({ productType: , }); // 动态生成的字段 const dynamicFields ref([]); // 状态 const isAnalyzing ref(false); const isSubmitting ref(false); const debugInfo ref(null); // 用于存储AI返回的原始信息便于调试 // 使用防抖避免用户每输入一个字符就调用一次API const debouncedAnalyzeForm _.debounce(() { if (formData.productType.trim().length 3) { // 当输入有一定内容时才分析 analyzeFormWithAI(); } else { // 输入内容太少清空动态字段 dynamicFields.value []; } }, 800); // 延迟800毫秒 /** * 核心函数调用AI分析当前表单输入并生成动态字段建议 */ async function analyzeFormWithAI() { if (isAnalyzing.value) return; isAnalyzing.value true; const userInput formData.productType; // 构建给AI的提示词Prompt const systemPrompt 你是一个专业的表单设计助手。请根据用户对产品类型的简短描述推断出收集该产品信息时最需要关注的3-5个属性字段。 请严格按照以下JSON数组格式回复不要有任何其他解释 [ { key: 字段唯一标识英文小写加下划线如brand, label: 字段显示标签中文如品牌, type: 字段类型只能是text, select, textarea, required: true/false, placeholder: 输入框提示文本可选, hint: 字段说明或示例可选, options: [选项1, 选项2] // 仅当type为select时需要 } ] 例如用户输入“智能手机”你可以返回关于品牌、操作系统、屏幕尺寸、内存等字段。; const userPrompt 用户描述的产品类型是“${userInput}”。请生成对应的表单字段。; try { const messages [ { role: system, content: systemPrompt }, { role: user, content: userPrompt } ]; const response await chatCompletion(messages, { temperature: 0.3, max_tokens: 800 }); // 降低随机性确保JSON格式 const aiReply response.choices[0]?.message?.content; debugInfo.value aiReply; // 保存原始回复供调试 // 尝试解析AI返回的JSON try { const parsedFields JSON.parse(aiReply); if (Array.isArray(parsedFields)) { dynamicFields.value parsedFields; // 初始化动态字段在formData中的值 parsedFields.forEach(field { if (!(field.key in formData)) { formData[field.key] field.type select ? : ; } }); } } catch (parseError) { console.error(解析AI返回的JSON失败:, parseError, 原始内容:, aiReply); // 可以在这里添加降级处理比如使用一组默认字段 } } catch (apiError) { console.error(AI分析表单失败:, apiError); // 可以给用户一个友好的错误提示 } finally { isAnalyzing.value false; } } /** * 处理表单提交 */ async function handleSubmit() { isSubmitting.value true; // 这里可以添加表单验证 const finalData { ...formData }; console.log(表单提交数据:, finalData); // 模拟API提交 await new Promise(resolve setTimeout(resolve, 1000)); alert(表单提交成功\n我们将处理您关于【${formData.productType}】的信息。); isSubmitting.value false; resetForm(); } /** * 重置表单 */ function resetForm() { Object.keys(formData).forEach(key { if (key ! productType) { // 保留第一个触发字段 delete formData[key]; } else { formData[key] ; } }); dynamicFields.value []; debugInfo.value null; } /script style scoped .smart-form { max-width: 600px; margin: 0 auto; padding: 2rem; border: 1px solid #e0e0e0; border-radius: 8px; background-color: #fafafa; } .form-group { margin-bottom: 1.5rem; } label { display: block; margin-bottom: 0.5rem; font-weight: 600; } input, select, textarea { width: 100%; padding: 0.75rem; border: 1px solid #ccc; border-radius: 4px; box-sizing: border-box; } .hint, .field-hint { font-size: 0.85rem; color: #666; margin-top: 0.25rem; } .dynamic-section { margin-top: 2rem; padding-top: 1.5rem; border-top: 2px dashed #4CAF50; } button { padding: 0.75rem 1.5rem; background-color: #4CAF50; color: white; border: none; border-radius: 4px; cursor: pointer; margin-right: 1rem; } button:disabled { background-color: #cccccc; cursor: not-allowed; } button.secondary { background-color: #757575; } .ai-thinking { margin-top: 1rem; padding: 1rem; background-color: #e3f2fd; border-radius: 4px; font-style: italic; } .debug-info { margin-top: 2rem; padding: 1rem; background-color: #f5f5f5; border: 1px solid #ddd; border-radius: 4px; font-size: 0.8rem; } /style3.2 智能表单的核心逻辑解析这个组件的核心在于analyzeFormWithAI函数。我们通过精心设计的提示词Prompt引导AI扮演“表单设计助手”的角色并强制它返回结构化的JSON数据。系统提示System Prompt定义了AI的角色和必须遵守的输出格式。明确的格式要求是让AI返回可解析数据的关键。用户输入将用户在产品类型输入框中的内容作为问题抛给AI。解析与渲染收到AI回复后尝试解析JSON并将解析出的字段数组dynamicFields渲染成对应的表单控件输入框、下拉框、文本框。用户体验通过防抖debounce避免频繁调用API通过加载状态isAnalyzing给用户即时反馈。现在你可以在App.vue中引入并使用这个组件了。试试在输入框里键入“数码相机”或“儿童绘本”看看AI会为你推荐哪些收集字段。你会发现表单从“死”的变成了“活”的它能根据上下文动态变化极大地提升了填写效率和用户体验。4. 实战二集成智能对话界面表单解决了“输入”的智能化而对话界面则解决了“交互”的智能化。我们将构建一个类似ChatGPT的聊天界面将其嵌入到一个模拟的“客服系统”中实现实时、连贯的问答。4.1 创建智能对话组件在src/components目录下创建SmartChat.vue。template div classsmart-chat div classchat-header h3智能客服助手/h3 p您好我是您的专属助手可以回答关于产品、订单、服务等各种问题。/p /div !-- 消息列表区域 -- div classchat-messages refmessagesContainer div v-for(message, index) in messages :keyindex :class[message, message.role] div classavatar {{ message.role user ? : }} /div div classbubble div classcontent v-htmlformatMessage(message.content)/div div classmeta span classrole{{ message.role user ? 您 : AI助手 }}/span span classtime{{ message.timestamp }}/span /div /div /div !-- AI思考中状态 -- div v-ifisThinking classmessage assistant thinking div classavatar/div div classbubble div classcontent span classtyping-indicator span/spanspan/spanspan/span /span /div /div /div /div !-- 输入区域 -- div classchat-input-area div classquick-actions button v-foraction in quickActions :keyaction.text clicksendQuickMessage(action.text) classquick-btn {{ action.text }} /button /div form submit.preventsendMessage classinput-form textarea v-modeluserInput keydown.enter.exact.preventsendMessage placeholder请输入您的问题... rows2 refinputTextarea /textarea button typesubmit :disabled!userInput.trim() || isThinking {{ isThinking ? 思考中... : 发送 }} /button /form p classinput-hint按 Enter 发送Shift Enter 换行。/p /div /div /template script setup import { ref, reactive, nextTick, watch } from vue; import { chatCompletion } from /services/api.js; // 消息历史 const messages ref([ { role: assistant, content: 您好我是智能客服助手。请问有什么可以帮您, timestamp: getCurrentTime() } ]); // 用户输入 const userInput ref(); // 状态 const isThinking ref(false); // DOM引用用于自动滚动 const messagesContainer ref(null); const inputTextarea ref(null); // 快捷操作 const quickActions reactive([ { text: 我的订单状态如何查询 }, { text: 产品保修政策是什么 }, { text: 如何申请退货 }, { text: 联系人工客服 } ]); /** * 发送消息 */ async function sendMessage() { const text userInput.value.trim(); if (!text || isThinking.value) return; // 1. 添加用户消息到列表 const userMessage { role: user, content: text, timestamp: getCurrentTime() }; messages.value.push(userMessage); userInput.value ; // 清空输入框 inputTextarea.value.focus(); // 重新聚焦 // 2. 设置AI思考状态 isThinking.value true; // 3. 调用AI API try { // 构建消息历史通常只保留最近N轮对话以控制token数量 const recentMessages messages.value.slice(-10).map(m ({ role: m.role, content: m.content })); const response await chatCompletion(recentMessages, { temperature: 0.8, // 对话可以稍具创造性 max_tokens: 800 }); const aiReply response.choices[0]?.message?.content; // 4. 添加AI回复到列表 const assistantMessage { role: assistant, content: aiReply, timestamp: getCurrentTime() }; messages.value.push(assistantMessage); } catch (error) { console.error(对话失败:, error); // 添加错误消息 const errorMessage { role: assistant, content: 抱歉我暂时无法处理您的请求。请稍后再试或联系人工客服。, timestamp: getCurrentTime() }; messages.value.push(errorMessage); } finally { isThinking.value false; // 滚动到底部 scrollToBottom(); } } /** * 发送快捷消息 */ function sendQuickMessage(text) { userInput.value text; // 等待下一个tick确保输入框已更新然后发送 nextTick(() { sendMessage(); }); } /** * 格式化消息内容简单处理换行 */ function formatMessage(content) { return content.replace(/\n/g, br); } /** * 获取当前时间字符串 */ function getCurrentTime() { const now new Date(); return ${now.getHours().toString().padStart(2, 0)}:${now.getMinutes().toString().padStart(2, 0)}; } /** * 滚动到消息底部 */ function scrollToBottom() { nextTick(() { if (messagesContainer.value) { messagesContainer.value.scrollTop messagesContainer.value.scrollHeight; } }); } // 监听消息变化自动滚动 watch(messages, () { scrollToBottom(); }, { deep: true }); /script style scoped .smart-chat { display: flex; flex-direction: column; height: 700px; max-width: 800px; margin: 0 auto; border: 1px solid #e0e0e0; border-radius: 12px; overflow: hidden; background-color: white; } .chat-header { padding: 1.5rem; background: linear-gradient(135deg, #6a11cb 0%, #2575fc 100%); color: white; } .chat-header h3 { margin: 0 0 0.5rem 0; } .chat-header p { margin: 0; opacity: 0.9; } .chat-messages { flex: 1; overflow-y: auto; padding: 1.5rem; background-color: #f5f7fa; } .message { display: flex; margin-bottom: 1.5rem; } .message.user { flex-direction: row-reverse; } .avatar { width: 40px; height: 40px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 1.5rem; flex-shrink: 0; margin: 0 0.75rem; } .message.user .avatar { background-color: #e3f2fd; } .message.assistant .avatar { background-color: #f3e5f5; } .bubble { max-width: 70%; padding: 0.75rem 1rem; border-radius: 18px; position: relative; } .message.user .bubble { background-color: #0084ff; color: white; border-bottom-right-radius: 4px; } .message.assistant .bubble { background-color: white; color: #333; border: 1px solid #e0e0e0; border-bottom-left-radius: 4px; } .bubble .content { line-height: 1.5; } .bubble .meta { margin-top: 0.5rem; font-size: 0.75rem; opacity: 0.7; display: flex; justify-content: space-between; } .message.thinking .bubble { background-color: transparent; border: none; padding: 0; } .typing-indicator { display: inline-flex; align-items: center; } .typing-indicator span { height: 8px; width: 8px; background-color: #999; border-radius: 50%; display: inline-block; margin-right: 4px; animation: typing 1.4s infinite both; } .typing-indicator span:nth-child(2) { animation-delay: 0.2s; } .typing-indicator span:nth-child(3) { animation-delay: 0.4s; } keyframes typing { 0%, 60%, 100% { transform: translateY(0); } 30% { transform: translateY(-8px); } } .chat-input-area { border-top: 1px solid #e0e0e0; padding: 1rem 1.5rem; background-color: white; } .quick-actions { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-bottom: 1rem; } .quick-btn { padding: 0.5rem 1rem; background-color: #f0f0f0; border: 1px solid #ddd; border-radius: 20px; font-size: 0.85rem; cursor: pointer; transition: all 0.2s; } .quick-btn:hover { background-color: #e0e0e0; } .input-form { display: flex; gap: 0.75rem; } .input-form textarea { flex: 1; padding: 0.75rem; border: 1px solid #ccc; border-radius: 8px; resize: none; font-family: inherit; font-size: 1rem; } .input-form button { padding: 0.75rem 1.5rem; background-color: #0084ff; color: white; border: none; border-radius: 8px; cursor: pointer; font-weight: 600; } .input-form button:disabled { background-color: #cccccc; cursor: not-allowed; } .input-hint { font-size: 0.8rem; color: #888; margin-top: 0.5rem; text-align: center; } /style4.2 对话组件的关键点这个组件模拟了一个完整的聊天交互体验消息管理使用messages数组维护对话历史每条消息包含角色user/assistant、内容和时间戳。上下文保持每次发送新消息时会将最近的对话历史例如最近10条发送给AI这样AI就能理解对话的上下文实现连贯的问答。用户体验优化思考状态isThinking状态和打字动画让用户知道AI正在处理。自动滚动新消息发出或到达时聊天区域会自动滚动到底部。快捷操作quickActions提供了常见问题模板方便用户快速提问。输入优化支持Enter发送ShiftEnter换行。错误处理API调用失败时会向用户展示友好的错误信息并保持界面可用。将SmartChat组件放入你的页面一个功能完备的智能客服对话界面就诞生了。你可以问它关于产品、订单、政策等各种问题体验流畅的对话过程。5. 实战三实现实时文本分析除了对话和表单AI另一个强大的能力是“理解”与“提炼”。我们可以在用户输入文本的同时实时提供摘要或情感分析这在内容编辑、评论审核、笔记整理等场景非常有用。5.1 创建实时文本分析组件在src/components目录下创建TextAnalyzer.vue。这个组件提供一个文本框用户输入时侧边栏实时显示AI生成的摘要和情感分析。template div classtext-analyzer div classeditor-section h3文本输入区/h3 textarea v-modelinputText inputdebouncedAnalyzeText placeholder请输入或粘贴一段文本进行分析... rows15 /textarea div classstats span字数{{ charCount }}/span span | /span span分析状态{{ analysisStatus }}/span /div /div div classanalysis-section h3AI实时分析结果/h3 div v-if!analysisResult !isAnalyzing classplaceholder p 请在左侧输入文本AI将自动为您分析。/p p尝试输入一段产品评论、新闻摘要或会议纪要。/p /div div v-else !-- 分析中状态 -- div v-ifisAnalyzing classanalyzing p正在分析文本.../p div classspinner/div /div !-- 分析结果 -- div v-else classresult div classresult-block h4 文本摘要/h4 p classsummary{{ analysisResult.summary || 未能生成摘要 }}/p /div div classresult-block h4 情感倾向/h4 div classsentiment span classsentiment-label{{ analysisResult.sentiment?.label || 中性 }}/span div classsentiment-bar div classsentiment-fill :style{ width: sentimentPercentage %, background-color: sentimentColor } /div /div span classsentiment-score置信度{{ (analysisResult.sentiment?.score * 100 || 0).toFixed(1) }}%/span /div p classsentiment-desc{{ sentimentDescription }}/p /div div classresult-block v-ifanalysisResult.keywords analysisResult.keywords.length 0 h4 关键词提取/h4 div classkeywords span v-forkeyword in analysisResult.keywords :keykeyword classkeyword-tag {{ keyword }} /span /div /div /div /div /div /div /template script setup import { ref, computed, watch } from vue; import { chatCompletion } from /services/api.js; import _ from lodash; const inputText ref(); const analysisResult ref(null); const isAnalyzing ref(false); const charCount computed(() inputText.value.length); const analysisStatus computed(() { if (isAnalyzing.value) return 分析中...; if (analysisResult.value) return 分析完成; return 等待输入; }); // 情感得分到颜色和描述的映射 const sentimentColor computed(() { const score analysisResult.value?.sentiment?.score; if (!score) return #95a5a6; // 中性灰 if (score 0.6) return #2ecc71; // 积极绿 if (score 0.3) return #3498db; // 略积极蓝 if (score -0.3) return #95a5a6; // 中性灰 if (score -0.6) return #e74c3c; // 略消极红 return #c0392b; // 消极深红 }); const sentimentPercentage computed(() { const score analysisResult.value?.sentiment?.score; if (!score) return 50; // 将-1到1的分数映射到0-100% return ((score 1) / 2) * 100; }); const sentimentDescription computed(() { const label analysisResult.value?.sentiment?.label; const score analysisResult.value?.sentiment?.score; if (!label || !score) return 情感倾向不明显。; const absScore Math.abs(score); let intensity ; if (absScore 0.7) intensity 非常; else if (absScore 0.4) intensity 比较; else intensity 略微; const baseDesc { 积极: 文本表达了${intensity}积极的情感。, 消极: 文本表达了${intensity}消极的情感。, 中性: 文本情感倾向为中性。 }; return baseDesc[label] || 情感分析完成。; }); // 防抖分析函数 const debouncedAnalyzeText _.debounce(() { if (inputText.value.trim().length 20) { // 文本长度阈值 analyzeText(); } else { // 文本太短清空结果 analysisResult.value null; } }, 1200); /** * 调用AI分析文本 */ async function analyzeText() { if (isAnalyzing.value) return; isAnalyzing.value true; const textToAnalyze inputText.value.trim(); // 构建分析提示词 const systemPrompt 你是一个专业的文本分析助手。请严格根据用户提供的文本生成一个包含以下三个字段的JSON对象 1. summary: 对文本核心内容的简要概括不超过100字。 2. sentiment: 一个对象包含label取值为“积极”、“消极”或“中性”和score一个介于-1到1之间的浮点数表示情感强烈程度。 3. keywords: 一个数组包含从文本中提取的3-5个最关键的名词或短语。 请只返回JSON对象不要有任何其他解释。; try { const messages [ { role: system, content: systemPrompt }, { role: user, content: 请分析以下文本\n\n${textToAnalyze} } ]; const response await chatCompletion(messages, { temperature: 0.1, max_tokens: 500 }); // 低随机性确保格式 const aiReply response.choices[0]?.message?.content; // 尝试解析JSON try { const parsedResult JSON.parse(aiReply); // 简单验证结构 if (parsedResult.summary parsedResult.sentiment parsedResult.keywords) { analysisResult.value parsedResult; } else { throw new Error(AI返回的JSON结构不完整); } } catch (parseError) { console.error(解析分析结果失败:, parseError); // 可以提供降级结果或错误提示 analysisResult.value { summary: AI分析结果解析失败请重试。, sentiment: { label: 中性, score: 0 }, keywords: [] }; } } catch (apiError) { console.error(文本分析API调用失败:, apiError); analysisResult.value { summary: 分析服务暂时不可用。, sentiment: { label: 中性, score: 0 }, keywords: [] }; } finally { isAnalyzing.value false; } } // 监听输入文本变化如果清空则重置结果 watch(inputText, (newVal) { if (newVal.trim().length 0) { analysisResult.value null; } }); /script style scoped .text-analyzer { display: grid; grid-template-columns: 1fr 1fr; gap: 2rem; max-width: 1200px; margin: 0 auto; padding: 2rem; } .editor-section, .analysis-section { display: flex; flex-direction: column; } h3 { margin-top: 0; color: #2c3e50; padding-bottom: 0.5rem; border-bottom: 2px solid #eee; } textarea { flex: 1; width: 100%; padding: 1rem; border: 1px solid #bdc3c7; border-radius: 8px; font-family: Monaco, Menlo, Ubuntu Mono, monospace; font-size: 0.95rem; line-height: 1.6; resize: vertical; margin-bottom: 1rem; } .stats { font-size: 0.9rem; color: #7f8c8d; text-align: right; } .placeholder { flex: 1; display: flex; flex-direction: column; justify-content: center; align-items: center; color: #95a5a6; text-align: center; font-style: italic; } .analyzing { flex: 1; display: flex; flex-direction: column; justify-content: center; align-items: center; color: #3498db; } .spinner { width: 40px; height: 40px; border: 4px solid rgba(52, 152, 219, 0.2); border-top: 4px solid #3498db; border-radius: 50%; animation: spin 1s linear infinite; margin-top: 1rem; } keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } .result { display: flex; flex-direction: column; gap: 1.5rem; } .result-block { background-color: #f8f9fa; padding: 1.25rem; border-radius: 8px; border-left: 4px solid #3498db; } .result-block h4 { margin-top: 0; margin-bottom: 0.75rem; color: #2c3e50; display: flex; align-items: center; gap: 0.5rem; } .summary { line-height: 1.6; margin: 0; white-space: pre-line; } .sentiment { display: flex; align-items: center; gap: 1rem; margin-bottom: 0.5rem; } .sentiment-label { font-weight: bold; min-width: 40px; } .sentiment-bar { flex: 1; height: 10px; background-color: #ecf0f1; border-radius: 5px; overflow: hidden; } .sentiment-fill { height: 100%; transition: width 0.5s ease; } .sentiment-score { font-size: 0.85rem; color: #7f8c8d; } .sentiment-desc { font-size: 0.9rem; color: #555; margin: 0.5rem 0 0 0; } .keywords { display: flex; flex-wrap: wrap; gap: 0.5rem; } .keyword-tag { background-color: #e1f5fe; color: #0277bd; padding: 0.25rem 0.75rem; border-radius: 20px; font-size: 0.85rem; } /style5.2 文本分析的价值这个组件展示了AI如何作为用户的“实时协作者”即时反馈用户一边输入AI一边分析结果实时呈现在侧边栏无需手动触发。多维洞察通过一个API调用我们同时获取了摘要、情感分析和关键词提取三种洞察信息密度很高。可视化呈现情感分析通过进度条和颜色直观展示关键词用标签云形式呈现让分析结果一目了然。应用广泛这个模式可以轻松扩展到其他分析任务如语法检查、风格建议、内容分类等。你可以把这段文本粘贴进去试试看“我刚收到你们的新款耳机音质真的太棒了低音沉稳有力高音清澈不刺耳佩戴也很舒适。不过蓝牙连接偶尔会断一下希望后续固件能优化。总体来说非常满意”6. 总结与展望走完这三个实战案例你应该能深切感受到将AI能力集成到Vue.js前端项目中并不是一件遥不可及的事情。核心思路很清晰通过API调用大模型用精心设计的提示词Prompt引导它完成特定任务然后在前端将返回的结构化数据优雅地呈现出来。智能表单让数据收集从“填空题”变成了“引导式对话”动态生成的字段更贴合用户的实际需求。智能对话界面则提供了近乎真人的交互体验能有效分担客服压力。实时文本分析更是将AI变成了一个随时在线的智能助手在你写作、阅读、处理信息时提供即时洞察。在实际项目中你还需要考虑更多工程化问题比如API密钥的安全管理、请求的节流与防抖、错误处理的用户体验、对话上下文的长度管理Token限制、以及更复杂的流式响应处理以获得更快的响应感。但万变不离其宗掌握了我们今天介绍的这种“前端Vue组件 后端AI API”的基本模式你就已经打开了智能应用开发的大门。前端的世界正在从“展示逻辑”走向“交互智能”而像SmallThinker-3B-Preview这样的轻量级模型正是我们手中最好用的工具之一。不妨就从今天这几个组件开始动手改造你的下一个项目给用户带来一点不一样的“智能”惊喜吧。获取更多AI镜像想探索更多AI镜像和应用场景访问 CSDN星图镜像广场提供丰富的预置镜像覆盖大模型推理、图像生成、视频生成、模型微调等多个领域支持一键部署。

相关文章:

Vue.js前端项目集成AI:SmallThinker-3B-Preview实现智能表单与对话

Vue.js前端项目集成AI:SmallThinker-3B-Preview实现智能表单与对话 1. 引言:当Vue.js遇见AI 你有没有遇到过这样的场景?用户填写一个复杂的表单,面对几十个选项不知所措;或者客服系统里,用户问了一个稍微…...

OpenClaw多模型混搭方案:百川2-13B-4bits与Qwen在自动化流程中的协同调用

OpenClaw多模型混搭方案:百川2-13B-4bits与Qwen在自动化流程中的协同调用 1. 为什么需要多模型混搭 去年冬天,当我第一次尝试用OpenClaw自动化处理周报时,发现一个尴尬的问题:用同一个模型处理文本润色和代码生成,效…...

2026 国内源码网站 TOP10:高速稳定 + 中文友好,开发者收藏版

对于国内开发者、站长、学生与创业团队来说,稳定高速、全中文、资源靠谱、无冗余广告的源码平台,能大幅降低开发成本、提升项目落地效率。2026 年实测筛选出国内综合体验 TOP10 源码站点,兼顾免费学习、商用部署、快速建站等场景,…...

OpenClaw定时任务专家:用Qwen3-32B镜像实现凌晨自动备份与报表生成

OpenClaw定时任务专家:用Qwen3-32B镜像实现凌晨自动备份与报表生成 1. 为什么需要定时任务自动化 作为一个经常需要处理数据库和报表的开发者,我发现自己总是在重复同样的工作:每天凌晨备份数据库、生成统计报表、然后发送给相关同事。这种…...

TlbbGmTool高效管理全流程实战指南:从部署到进阶的完整解决方案

TlbbGmTool高效管理全流程实战指南:从部署到进阶的完整解决方案 【免费下载链接】TlbbGmTool 某网络游戏的单机版本GM工具 项目地址: https://gitcode.com/gh_mirrors/tl/TlbbGmTool 在《天龙八部》游戏服务器管理中,管理员常常面临账号管理繁琐、…...

国内外优秀的源码网站,程序员必备收藏

在快节奏的开发环境中,高效获取优质源码已成为提升开发效率的关键。无论是快速搭建项目原型、学习优秀代码架构,还是寻找商业级系统解决方案,一个可靠的源码平台能为你节省大量时间和精力。今天,我将为大家分享一个近期在开发者圈…...

Java毕业设计基于springboot+vue的旧时光咖啡厅管理系统

前言 该系统旨在提高咖啡厅的运营效率和服务质量,通过集成订单管理、库存管理、员工管理、客户管理等多个功能模块,实现对咖啡厅日常运营的全面管理。同时,系统还提供了丰富的数据分析和报表功能,帮助管理者更好地了解咖啡厅的运营…...

告别转换限制:实测可免费批量处理Geojson、Shapefile与KML的在线工具指南

1. 为什么你需要这个免费批量转换工具? 作为一个经常处理地理信息数据的老手,我太懂你们遇到的痛点了。上周帮学弟改毕业论文,他用的那个知名在线转换工具,刚传了第4个文件就弹出"本月免费额度已用完"——这哪够用啊&am…...

VGG‘文艺复兴’背后的思考:从RepVGG看AI模型设计的‘简’与‘繁’哲学

VGG式架构的当代启示:当模型设计遇见"大道至简"的智慧 在深度学习模型架构的演进历程中,我们见证了一场耐人寻味的"轮回"——从早期VGG的极简主义,到Inception、ResNet等复杂多分支结构的盛行,再到如今RepVGG…...

微信毕业设计基于微信小程序的易物小店交换系统

前言 Spring Boot 易物小店交换系统是一个基于 Web 的应用程序,利用 Spring Boot 框架构建,主要用于帮助用户实现物品交换的功能。该系统为用户提供了一个便捷、安全、高效的平台,让他们能够轻松地发布自己想要交换的物品信息,寻找…...

基于FPGA的DDS在安路TD和EG4A20BG256上的调试技巧与实战经验(五)

1. 安路TD软件常见编译问题排查指南 第一次用安路TD软件编译DDS工程时,我遇到了几个典型的编译错误。最常见的就是license报错,这个坑我踩过三次。当你看到"License expired"或者"Invalid license"提示时,别急着重装软件…...

告别collect2.exe和ld报错:VSCode C语言环境从配置到避坑的完整指南

从零构建VSCode C语言开发环境:编译错误诊断与高效配置指南 当你在VSCode中按下F5期待看到第一个"C语言Hello World"程序运行时,却迎面撞上"undefined reference to WinMain"和"collect2.exe: error: ld returned 1 exit statu…...

Windows下OpenClaw全流程指南:接入Qwen3.5-4B-Claude完成办公自动化

Windows下OpenClaw全流程指南:接入Qwen3.5-4B-Claude完成办公自动化 1. 为什么选择OpenClaw做办公自动化 去年我接手了一个新项目,每周需要处理几十份会议录音转写的文字稿。手动整理不仅耗时,还经常漏掉关键行动项。当我第一次听说OpenCla…...

Tiled2Unity:Tiled地图与Unity引擎的无缝数据转换解决方案

Tiled2Unity:Tiled地图与Unity引擎的无缝数据转换解决方案 【免费下载链接】Tiled2Unity Export Tiled Map Editor (TMX) files into Unity 项目地址: https://gitcode.com/gh_mirrors/ti/Tiled2Unity 副标题:基于自动化工作流的2D游戏地图资产转…...

从Hightec/TASKING到ADS:手把手教你迁移AURIX工程并优化编译配置

1. 为什么需要从Hightec/TASKING迁移到ADS? 对于使用AURIX系列芯片的开发者来说,Hightec和TASKING这两个商业IDE一直是主流选择。但最近几年,越来越多的开发者开始转向英飞凌官方推出的AURIX Development Studio(ADS)&…...

5个必知技巧:快速掌握Hearthstone-Script提升炉石传说游戏体验

5个必知技巧:快速掌握Hearthstone-Script提升炉石传说游戏体验 【免费下载链接】Hearthstone-Script Hearthstone script(炉石传说脚本)(2024.01.25停更至国服回归) 项目地址: https://gitcode.com/gh_mirrors/he/He…...

从期末试卷到实战指南:通信原理核心考点深度解析与应用

1. 从试卷到实战:HDB3码的工程应用解析 当年我第一次在实验室调试E1线路时,遇到时钟同步问题差点崩溃。示波器上那些诡异的波形让我突然想起期末考卷里那道HDB3码的考题——原来教授不是在为难我们,而是在为今天的实战埋下伏笔。 HDB3码作为通…...

UltraStar Deluxe实战指南:免费打造专业级家庭KTV系统

UltraStar Deluxe实战指南:免费打造专业级家庭KTV系统 【免费下载链接】USDX The free and open source karaoke singing game UltraStar Deluxe, inspired by Sony SingStar™ 项目地址: https://gitcode.com/gh_mirrors/us/USDX 还在为KTV包厢的高昂费用而…...

3步解决AEUX图层对齐问题的完整指南

3步解决AEUX图层对齐问题的完整指南 【免费下载链接】AEUX Editable After Effects layers from Sketch artboards 项目地址: https://gitcode.com/gh_mirrors/ae/AEUX AEUX作为连接设计工具与After Effects的桥梁,是设计师实现高效工作流的关键。然而在实际…...

SpringBoot集成gRPC踩坑指南:从.proto文件到服务调用的完整流程

SpringBoot与gRPC深度整合实战:从协议定义到生产级部署 在微服务架构盛行的今天,跨语言服务调用已成为刚需。作为Google开源的RPC框架,gRPC凭借其基于HTTP/2的高效传输和Protocol Buffers的紧凑序列化,在分布式系统中展现出独特优…...

3个超实用步骤:用DS4Windows让PS手柄在Windows游戏中完美适配

3个超实用步骤:用DS4Windows让PS手柄在Windows游戏中完美适配 【免费下载链接】DS4Windows Like those other ds4tools, but sexier 项目地址: https://gitcode.com/gh_mirrors/ds/DS4Windows 还在为PS4/PS5手柄在Windows游戏中无法正常使用而困扰吗&#xf…...

OpenClaw+Qwen3-32B自动化办公:会议纪要生成与飞书同步实战

OpenClawQwen3-32B自动化办公:会议纪要生成与飞书同步实战 1. 为什么需要自动化会议纪要 每次开完会最痛苦的事情是什么?对我来说就是整理会议纪要。作为技术负责人,每周要参加5-6个不同主题的会议,会后需要花大量时间回听录音、…...

实践指南:借助LLaMa-Factory高效定制你的专属LLaMa3

1. 为什么选择LLaMa-Factory微调LLaMa3? 第一次尝试微调大语言模型时,我花了整整三天时间在环境配置上。从CUDA版本冲突到PyTorch依赖问题,各种报错让人崩溃。直到发现LLaMa-Factory这个"微调瑞士军刀",才明白原来大模型…...

3个核心价值:XianyuAutoAgent监控系统全解析

3个核心价值:XianyuAutoAgent监控系统全解析 【免费下载链接】XianyuAutoAgent 智能闲鱼客服机器人系统:专为闲鱼平台打造的AI值守解决方案,实现闲鱼平台724小时自动化值守,支持多专家协同决策、智能议价和上下文感知对话。 项目…...

认知研究避坑指南:为什么CHARLS数据需要按教育程度分层修正?

认知研究避坑指南:教育程度分层在CHARLS数据修正中的关键作用 老龄化认知研究领域的数据分析常常面临一个棘手问题:如何确保不同时间点收集的认知测试分数具有可比性?中国健康与养老追踪调查(CHARLS)作为国内重要的老龄…...

Linux网络开发实战:如何用MDIO总线扫描PHY设备并注册驱动(附完整代码解析)

Linux网络开发实战:MDIO总线扫描PHY设备与驱动注册全解析 在嵌入式Linux网络设备开发中,PHY芯片作为物理层接口的核心组件,其驱动加载和设备管理机制直接影响网络功能的稳定性。MDIO总线作为连接MAC控制器与PHY芯片的标准接口,其扫…...

面向生产的Chatgpt5.4:系统集成、架构模式与成本优化深度拆解

对于计划将顶级AI能力深度集成至自身产品与工作流的团队而言,理解Gemini 3.1 Pro的系统级特性、集成模式与全生命周期成本至关重要。国内开发者可通过RskAi(www.rsk.cn)等聚合平台,以零成本、国内直访的方式完成前期技术验证与原型…...

PDE建模技术在油水两相流及离散裂缝模型中的应用:深入探讨Comsol石油工程中的关键概念

comsol石油工程 pde油水两相流 pde油水离散裂缝两相流概念模型附赠视频讲解和推导过程 采用PDE建模当油和水在岩石孔隙里掐架石油工程里最头疼的问题之一就是油水两相流。想象一下,地下的油像挤牙膏一样被水推着走,结果要么水窜得太快把油路截断&#xf…...

别再手动写DSP了!Vivado里用Multiply Adder IP核实现MAC运算的保姆级教程

高效实现MAC运算:Vivado中Multiply Adder IP核的工程实践指南 在FPGA开发中,乘累加(MAC)运算作为数字信号处理的核心操作,其实现效率直接影响系统性能。传统手写RTL代码不仅耗时,还容易引入时序问题和资源浪…...

OpenClaw多任务队列:nanobot处理并行请求方案

OpenClaw多任务队列:nanobot处理并行请求方案 1. 问题背景与需求场景 上周我在本地部署了一个基于OpenClaw的自动化助手,用于处理日常办公中的重复性任务。最初只是简单对接了单一大模型实例,但随着使用频率增加,很快遇到了一个…...