切換語言為:簡體

透過 Vue 使用 Tailwind CSS 實現一個 ChatGPT 聊天機器人

  • 爱糖宝
  • 2024-07-15
  • 2123
  • 0
  • 0

最近覺得自己對vue愈加熟練,就決定利用tailwindcss手搓一個智慧聊天機器人,用了不到一個下午就完成了,不用自己寫樣式確實爽(雖然這次也沒用到什麼樣式),下圖為實現效果:

透過 Vue 使用 Tailwind CSS 實現一個 ChatGPT 聊天機器人

tailwindcss

有些小夥伴可能不知道tailwindcss是什麼,它其實就是一個CSS框架,讓我們可以不用自己辛辛苦苦寫樣式了,各種各樣的樣式,只有你想不到的,沒有它做不到。我們只需要給上正確的類名,樣式就生效了。

如何在vue專案中引入

1. 安裝依賴

在整合終端中開啟對應專案並輸入指令:

npm install -D tailwindcss postcss autoprefixer

2. 初始化配置

繼續輸入指令:

npx tailwindcss init

3. 引入樣式

在全域性樣式檔案中引入Tailwind CSS:

/* ./src/main.css */
@import 'tailwindcss/base';
@import 'tailwindcss/components';
@import 'tailwindcss/utilities';

然後我們就可以在我們的專案中使用Tailwind CSS了,我這一整個聊天機器人的元素樣式都是透過它來實現的。

實現過程

檔案整體結構

透過 Vue 使用 Tailwind CSS 實現一個 ChatGPT 聊天機器人

各檔案功能介紹及原始碼

src\libs\gpt.js(向chat傳送請求,拿取資料)
export const chat = async (messages,apiKey) => {
    try{
        const result = await fetch("https://api.302.ai/v1/chat/completions",{
            method:"POST",
            headers:{
                "Content-Type":"application/json",
                // 授權資訊
                "Authorization":`Bearer ${apiKey}`
            },
            body:JSON.stringify({
                model:"gpt-3.5-turbo",
                messages:messages
            })
        })
        const data = await result.json()
        console.log(data);
        return data.choices[0].message.content
    }catch(err){
        throw(err)
    }
}

src\router\index.js (配置路由)
import { createRouter,createWebHashHistory } from 'vue-router'

const router = createRouter({
    history:createWebHashHistory(),
    routes:[
        {
            path:'/',
            name:'home',
            // 頁面級別元件 views
            component:() => import('../views/home.vue')
        }

    ]
})

export default router

src\App.vue (引入路由頁面)
<template>
  <div>
    <router-view />
  </div>
</template>

<script setup>

</script>

<style scoped>

</style>

src\main.js (引入tailwindcss並使用路由)
import { createApp } from 'vue'
import './assets/tailwind.css'
import App from './App.vue'
import router from './router'

const app = createApp(App)
app
    .use(router)
    .mount('#app')

src\views\home.vue (主體部分)
<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 class="group flex flex-col px-4 py-3 rounded-lg"
                v-for="item of messageList.filter((v) => v.role != 'system')">
                <div class="flex justify-between item-center mb-2">
                    {{ item.role }}:
                    <div>
                        {{ 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="messageContent"
                    @keydown.enter="SendOrSave()" />
                <button class="btn ml-4" :disabled="isTalking" @click="SendOrSave()">儲存</button>
            </div>
        </div>
    </div>
</template>
<script setup>
import { chat } from '../libs/gpt'
import { ref, onMounted } from 'vue'
const messageContent = ref('')
const isConfig = ref(true)
const isTalking = ref(false)
const messageList = ref([
    {
        role: 'system',
        content: "你是人工智慧客服,請儘可能簡潔回答問題"
    },
    {
        role: 'assistant',
        content: `
        你好,我是AI語言模型,我可以提供一些常用服務和資訊,例如:

        1. 翻譯:我可以把中文翻譯成英文,英文翻譯成中文,還有其他一些語言翻譯,比如法語、日語、西班牙語等。

        2. 諮詢服務:如果你有任何問題需要諮詢,例如健康、法律、投資等方面,我可以儘可能為你提供幫助。

        3. 閒聊:如果你感到寂寞或無聊,我們可以聊一些有趣的話題,以減輕你的壓力。

        請告訴我你需要哪方面的幫助,我會根據你的需求給你提供相應的資訊和建議。
        `
    }
])
const clickConfig = () => {
    isConfig.value = true
}
onMounted(() => {
    if (getApiKey()) {
        isConfig.value = false
    }
})
const SendOrSave = () => {
    if (!messageContent.value.length) return;
    if (isConfig.value) {
        // save api-key
        if (saveAPIKey(messageContent.value.trim())) {
            isConfig.value = false
        }
        messageContent.value = ''
    } else {
        // send message
        sendMessage()
    }
}
const saveAPIKey = (apiKey) => {
    localStorage.setItem('apiKey', apiKey);
    return true
}
const getApiKey = () => {
    return localStorage.getItem('apiKey')
}
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
        })
    } catch (err) {
        console.log('失敗');
    } finally {
        isTalking.value = false
    }
}
</script>
<style></style>

包含頁面主題內容提示詞以及apikey的儲存。這裏要注意的是輸入apikey與輸入問題用的是同一個input

0則評論

您的電子郵件等資訊不會被公開,以下所有項目均必填

OK! You can skip this field.