背景:
甲方爸爸发来工作请求写一个这样的chatGPT页面。
收到甲方爸爸的工作请求后,作为乙方的我听到金主给的价格后我答应一天后交付,直接开干。文章源自灵鲨社区-https://www.0s52.com/bcjc/vue-jsjc/16861.html
切图崽第一步——设计结构css
一般的项目我们都是设计都是使用选择器来规定样式,这样的做法虽然有极高的定制自由度,但同时也可能增加项目的复杂度和维护成本,时间成本太高,不符合我们的切图逻辑,我们切图崽的宗旨就是快,准,稳文章源自灵鲨社区-https://www.0s52.com/bcjc/vue-jsjc/16861.html
tailwindcss
Tailwind CSS 是一款流行的原子类(utility-first)CSS框架,它彻底改变了前端开发者编写样式的方式。与传统的CSS框架不同,Tailwind CSS 不是以预设的组件为中心,而是提供了一套广泛、细粒度的类,这些类可以直接应用于HTML元素上,以实现快速、一致的界面设计。文章源自灵鲨社区-https://www.0s52.com/bcjc/vue-jsjc/16861.html
安装 Tailwind CSS
java
npm install -D tailwindcss@latest postcss@latest autoprefixer@latest
初始化 Tailwind CSS
csharp
npx tailwindcss init -p
配置模板文件的路径
在 tailwind.config.js
配置文件中添加所有模板文件的路径。文章源自灵鲨社区-https://www.0s52.com/bcjc/vue-jsjc/16861.html
css
/** @type {import('tailwindcss').Config} */
module.exports = { content: ["./src/**/*.{html,js}"],
theme: { extend: {}, },
plugins: [],
}
将加载 Tailwind 的指令添加到你的 CSS 文件中
在你的主 CSS 文件中通过 @tailwind
指令添加每一个 Tailwind 功能模块。文章源自灵鲨社区-https://www.0s52.com/bcjc/vue-jsjc/16861.html
less
@tailwind base;
@tailwind components;
@tailwind utilities;
在
index.js
文件中引入 Tailwind.css
文件所在位置 配置完成后我们便可以在HTML元素上直接使用Tailwind的类名了:文章源自灵鲨社区-https://www.0s52.com/bcjc/vue-jsjc/16861.html
文章源自灵鲨社区-https://www.0s52.com/bcjc/vue-jsjc/16861.html
文章源自灵鲨社区-https://www.0s52.com/bcjc/vue-jsjc/16861.html
这些样式一眼看过去相信大家都能看出是代表这什么,不清楚这些样式格式和代表的看这里:TailwindCSS中文文档 | TailwindCSS中文网文章源自灵鲨社区-https://www.0s52.com/bcjc/vue-jsjc/16861.html
切图崽的完成的结构文章源自灵鲨社区-https://www.0s52.com/bcjc/vue-jsjc/16861.html
ini
<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 class="flex-1 mx-2 mt-20 mb-2">
<div
v-for="item in messageList.filter(v => v.role != 'system')"
class="group flex flex-col px-4 py-3 rounded-lg" >
<div class="flex justify-between item-center mb-2">
{{ item.role }}:
<div class="w-11/12">
{{ item.content }}
</div>
</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" v-if="isConfig">
请输入API KEY:
</div>
<div class="flex">
<input class="input flex-1"
:type="isConfig?'password':'text'"
:placeholder="isConfig?'sk-xxxxxx':'请输入...'"
v-model="msgContent"
@keydown.enter="sendOnSave()"
/>
<button class="btn ml-4" :disabled="isTalking" @click="sendOnSave()">保存</button>
</div>
</div>
</div>
</template>
切图崽第二步——JS逻辑设计
- 输入框有两种状态:
- 输入API Key:这是初始状态,用户可以在此处输入他们的API Key。
- 输出问题:在用户输入并保存了API Key之后,此输入框将用于显示问题或接收用户的输入。
- 按钮有三种状态:
- 默认状态:用户可以自由输入和提交。
- 锁定状态:当用户输入并提交后,按钮会锁定以防止重复提交,直到服务器返回响应。
- 解锁状态:一旦服务器返回响应,按钮将解锁,允许用户再次提交新的请求。
- “设置”按钮位于右上角,它可能提供一个弹出菜单或者链接到另一个页面,用于调整其他相关设置。
xml
<script setup>
import { ref ,onMounted } from 'vue';
import { chat } from '../libs/gpt'
onMounted(()=>{
if(getApikey()){
isConfig.value=false
}
})
const saveAPIKey=(apiKey)=>{
localStorage.setItem('apiKey',apiKey)
return true
}
const getApikey=()=>{
return localStorage.getItem('apiKey')
}
let isConfig=ref(true)//true API key的设置false聊天
let msgContent=ref('')
let isTalking=ref(false)//LLM正在返回
const clickConfig=()=>{
isConfig.value=true
msgContent.value=''
}
const sendOnSave=()=>{
if(!msgContent.value.length) return
if(isConfig.value){
//save api-key
if(saveAPIKey(msgContent.value.trim())){
isConfig.value=false
}
msgContent.value=''
}else{
//send message
sendMessage()
}
}
const messageList=ref([
{
role:'system',
content:'你是一个人工只能客服,请尽可能简介回答问题'
},
{
role:'assistant',
content: `你好,我是AI语言模型,我可以提供一些常用服务和信息,例如:
1. 翻译:我可以把中文翻译成英文,英文翻译成中文,还有其他一些语言翻译,比如法语、日语、西班牙语等。
2. 咨询服务:如果你有任何问题需要咨询,例如健康、法律、投资等方面,我可以尽可能为你提供帮助。
3. 闲聊:如果你感到寂寞或无聊,我们可以聊一些有趣的话题,以减轻你的压力。
请告诉我你需要哪方面的帮助,我会根据你的需求给你提供相应的信息和建议。`
}
])
const sendMessage=async()=>{
//send message to chatgpt
const message=msgContent.value.trim()
try{
isTalking.value=true
messageList.value.push({
role:'user',
content:message
})
const data=await chat(messageList.value,getApikey(messageList))
messageList.value.push({
role:'assistant',
content:data
})
msgContent.value=''
}catch(error){
}finally{
isTalking.value=false
}
}
</script>
这里我们调用了openai
的请求封装在了libs/gpt'
文件中,文件内容配置原来写过一篇文章,可以在这里看:使用openai模块包自建一个在线GPT聊天机器人
打工人的结尾
随着最后一行代码的敲击,切图崽轻轻靠在椅背上,凝视着屏幕上那经过雕琢的网页。窗外的夜色已深,只剩键盘冷却后的寂静和显示屏微弱的光晕。老板还算满意,给了我牛马费,结束牛马切图崽的一天。
评论