punine-design
v0.0.5
Published
一个基于 Vue 3 的 AI 聊天插件,通过Langchain.js、DeepSeek API Key快速构建自定义的AI聊天应用。
Readme
PuNINE-Design(快速构建流式响应AI应用的现代化组件库)
一个基于 Vue 3 的 AI 聊天组件库,通过 DeepSeek API Key 快速构建自定义的 AI 聊天应用。提供完整的聊天界面组件,支持代码高亮、一键复制等功能。
📦 组件库特点
- 💬 完整的聊天组件:提供
Pn-chatContainer这个核心组件 - 📋 代码处理能力:自动语法高亮和一键复制功能
- 📐 灵活的尺寸控制:支持动态传递长宽、颜色等样式参数
- 🎨 可定制外观:支持自定义背景色、文字颜色、标题等
- 🚀 响应式设计:适配不同屏幕尺寸的设备
- 🔧 TypeScript 支持:提供完整的类型定义
- 🌐 多种使用方式:可作为插件全局注册或单独导入组件
- 🍍 Pinia 集成:内置状态管理,处理聊天消息数据
📋 快速安装
前提条件
- Vue 3.0+
- TypeScript(可选,但推荐)
- Node.js 16.0.0 或更高版本
- Pinia(已内置依赖,但需在项目中正确初始化)
使用 npm
npm install punine-design使用 pnpm
pnpm i punine-design使用 yarn
yarn add punine-design🔑 API Key 配置
使用本组件库前,您必须通过组件属性传递 DeepSeek API Key。
通过组件属性配置
直接在组件上传递 API Key 和可选的模型名称:
<!-- 基本用法 -->
<Pn-chatContainer
width="800px"
height="600px"
apiKey="your_api_key_here"
/>
<!-- 自定义模型名称 -->
<Pn-chatContainer
width="800px"
height="600px"
apiKey="your_api_key_here"
modelName="deepseek-3.5"
/>注意:
apiKey是必需属性,必须提供有效的 DeepSeek API Key,否则组件无法正常使用AI功能modelName是可选属性,默认为 'deepseek-chat'- 重要安全提示: 确保妥善保管您的 API Key,不要将其硬编码在公开代码中,建议使用环境变量或安全的配置管理方式
🔧 环境配置
在您的项目根目录创建 .env 文件,并添加以下环境变量:
# DeepSeek API Key(必需)
VITE_DEEPSEEK_API_KEY=your_api_key_here
# 可选:指定使用的模型名称(默认为 'deepseek-chat')
VITE_MODEL_NAME=deepseek-chat🚀 组件库使用指南
组件库支持两种主要使用方式:全局注册和局部导入。
方式一:全局注册(推荐用于在多个组件中使用)
在项目入口文件中注册整个组件库:
// main.js 或 main.ts
import { createApp } from 'vue'
import { createPinia } from 'pinia' // 必须先导入并初始化 Pinia
import App from './App.vue'
import PnDesignPlugin from 'punine-design'
import 'punine-design/dist/ai-chat-plugin.css'
const app = createApp(App)
const pinia = createPinia()
// 注意:必须先安装 Pinia
app.use(pinia)
// 然后再安装聊天插件
app.use(PnDesignPlugin)
app.mount('#app')全局注册后,可以在任何组件中直接使用:
<template>
<div class="chat-app">
<h1>AI 聊天界面</h1>
<Pn-chatContainer
width="800px"
height="600px"
apiKey="your_api_key_here"
/>
</div>
</template>
<script setup>
// 全局注册后,无需在此处导入组件
</script>方式二:局部导入(推荐用于仅在单个组件中使用)
<template>
<div class="chat-app">
<h1>AI 聊天界面</h1>
<Pn-chatContainer
width="800px"
height="600px"
apiKey="your_api_key_here"
/>
</div>
</template>
<script setup>
// 导入组件
import { PnChatContainer } from 'punine-design'
import 'punine-design/dist/ai-chat-plugin.css'
</script>📚 组件 API 文档
Pn-chatContainer 组件 (核心组件)
聊天主容器组件,内部已自动嵌套输入框组件,集成了完整的聊天功能。聊天界面中包含黑白相间的小球动画效果,加载动画背景为半透明樱花粉,提升用户交互体验。
属性参数
| 参数名 | 类型 | 默认值 | 说明 | | --------------- | ------ | --------------------- | --------------------------------------------- | | width | string | '100%' | 聊天容器的宽度 | | height | string | 'calc(100vh - 120px)' | 聊天容器的高度 | | backgroundColor | string | '#f7f7f7' | 聊天容器的背景颜色 | | color | string | '#333' | 聊天容器的文字颜色 | | title | string | 'AI 助手' | 聊天容器顶部的标题 | | apiKey | string | 无(必需) | DeepSeek API Key,必须提供才能使用AI功能 | | modelName | string | 'deepseek-chat' | AI模型名称,默认为'deepseek-chat' |
示例
<Pn-chatContainer
width="800px"
height="600px"
backgroundColor="#ffffff"
color="#444444"
title="我的AI助手"
apiKey="your_api_key_here"
modelName="deepseek-chat"
/>Pn-card 组件 (卡片组件)
可自定义的卡片组件,支持设置卡片的基本属性。
属性参数
| 参数名 | 类型 | 默认值 | 说明 | | ------------- | ------ | ------ | ------------- | | width | string | '' | 卡片的宽度 | | height | string | '' | 卡片的高度 | | img | string | '' | 卡片的图像URL | | title | string | '' | 卡片的标题 | | description | string | '' | 卡片的描述文字|
事件
Pn-loading 组件 (加载动画组件)
全屏加载动画组件,支持三种使用方式:组件方式、指令方式和属性方式。全屏模式下加载动画会固定在页面上,即使滚动页面也会保持在视野中央。加载动画背景为半透明浅蓝色,包含黑白相间的小球旋转动画效果。
组件方式使用
<Pn-loading
:visible="true"
text="加载中..."
:fullscreen="true"
/>指令方式使用 (推荐)
使用v-Pn-loading指令控制加载动画:
<!-- 使用指令方式 -->
<button v-Pn-loading="isLoading">点击加载</button>
<!-- 或小写格式 -->
<div v-pn-loading="isLoading">内容区域</div>属性方式使用
在任意HTML标签上通过Pn-loading属性控制全屏加载动画:
<!-- 使用属性方式 -->
<button Pn-loading="true">显示加载</button>
<button Pn-loading="false">隐藏加载</button>
<!-- 或小写格式 -->
<div pn-loading="isLoading">内容区域</div>注意: 属性方式会自动监听属性值的变化,当值为'true'、'1'或空字符串时显示加载动画,其他值则隐藏。
编程式使用
<script setup>
import { $loading } from 'punine-design'
// 显示全屏加载
const loadingInstance = $loading.service({
text: '加载中...',
fullscreen: true
})
// 关闭加载
setTimeout(() => {
loadingInstance.close()
}, 2000)
</script>Pn-p 组件 (段落组件)
用于展示文本内容的段落组件,支持自定义样式和布局。
属性参数
| 参数名 | 类型 | 默认值 | 说明 | | ------------- | ------ | ------ | ------------- | | content | string | '' | 段落内容 | | color | string | '#333' | 文字颜色 | | fontSize | string | '14px' | 字体大小 | | lineHeight | string | '1.5' | 行高 | | textAlign | string | 'left' | 文本对齐方式 |
示例
<Pn-p
content="这是一段示例文本内容,支持自定义样式。"
color="#555"
fontSize="16px"
lineHeight="1.8"
textAlign="center"
/>使用技巧
- 可以通过content属性传递多行文本内容,组件会自动处理换行
- 结合CSS变量可以实现更灵活的样式定制
- 适用于展示段落、说明文字、帮助信息等场景
- 单个卡片模式下,组件会自动为卡片生成一个id为'single-card'
- 多卡片模式下,dataset数组中的每项必须包含id、name、img字段,description字段可选
Pn-loading 组件 (加载动画组件)
一加载动画组件,支持组件方式、指令方式和编程式调用三种使用方式。
属性
| 属性名 | 类型 | 默认值 | 说明 | |-------|------|-------|------| | visible | boolean | false | 是否显示加载动画 | | fullscreen | boolean | false | 是否全屏显示 | | text | string | '加载中...' | 加载文本提示 | | background | string | 'rgba(255, 255, 255, 0.9)' | 背景颜色 | | color | string | '#409eff' | 加载动画颜色 | | size | string | '20px' | 点的大小 |
示例
1. 组件方式使用
<template>
<div>
<PnLoading
:visible="showLoading"
text="加载中..."
/>
<button @click="showLoading = !showLoading">
{{ showLoading ? '隐藏' : '显示' }} 加载动画
</button>
</div>
</template>
<script setup>
import { ref } from 'vue'
import PnLoading from './components/Pn-loading.vue'
const showLoading = ref(false)
</script>2. 自定义样式
<PnLoading
:visible="showLoading"
text="处理数据中"
color="#e74c3c"
background="rgba(0, 0, 0, 0.5)"
size="15px"
/>3. 指令方式使用
<template>
<div
v-loading="loading"
element-loading-text="指令加载中"
element-loading-background="rgba(255, 255, 255, 0.8)"
>
这是一个使用v-loading指令的元素
</div>
</template>
<script setup>
import { ref } from 'vue'
const loading = ref(false)
</script>4. 编程式使用
<template>
<button @click="showProgrammaticLoading">
显示全屏加载动画
</button>
</template>
<script setup>
import { Loading } from './utils/loading'
const showProgrammaticLoading = () => {
const loadingInstance = Loading.service({
text: '全屏加载中...',
background: 'rgba(0, 0, 0, 0.6)',
color: '#409eff'
})
// 3秒后自动关闭
setTimeout(() => {
loadingInstance.close()
}, 3000)
}
</script>Pn-opening 组件 (动画标题组件)
一个带有缩放动画效果的标题组件,支持自定义字体大小、颜色、位置和背景图片,适合作为页面开场动画或重点内容的标题展示。
属性
| 属性名 | 类型 | 默认值 | 描述 | |--------|------|--------|------| | size | String | '12vw' | 最终动画完成时的字体大小 | | fontImg | String | '' | 动画开始时字体里面的图片 | | color | String | '#fff' | 最终动画完成时的字体颜色 | | backgroundImg | String | '' | 文字的背景图 | | top | String | undefined | 展示文字的顶部位置 | | left | String | undefined | 展示文字的左侧位置 | | right | String | undefined | 展示文字的右侧位置 | | bottom | String | undefined | 展示文字的底部位置 | | text | String | 'TITLE' | 文字内容 | | duration | String | '1s' | 动画持续时间 |
示例
<!-- 基本用法 -->
<Pn-opening
text="欢迎"
size="20vw"
color="#3498db"
/>
<!-- 自定义大小和颜色 -->
<Pn-opening
text="探索"
size="15vw"
color="#e74c3c"
duration="1.5s"
/>
<!-- 使用背景图 -->
<Pn-opening
text="创意"
size="18vw"
backgroundImg="https://picsum.photos/id/29/800/400"
/>
<!-- 位置控制 -->
<Pn-opening
text="置顶"
size="8vw"
color="#2ecc71"
top="20px"
left="20px"
/>Pn-float 组件 (3D旋转卡片组件)
3D环形旋转卡片组件,支持自定义卡片数量、大小、颜色和旋转效果。您可以用这个组件构造网站的首页大屏轮播图、或者在展示区域使用该组件库
属性参数
| 参数名 | 类型 | 默认值 | 说明 | |--------|------|--------|------| | number | Number | 6 | 卡片数量,取值范围2-20 | | radius | String | '10px' | 卡片圆角大小 | | cardWidth | String | '175px' | 卡片宽度 | | cardHeight | String | '120px' | 卡片高度 | | orbitRadius | Number | 200 | 旋转轨道半径 | | rotateDuration | Number | 20 | 旋转周期(秒) | | pauseOnHover | Boolean | true | 鼠标悬停时是否暂停旋转 | | frontColor | String | '' | 卡片正面颜色,支持纯色和渐变色 | | backColor | String | '' | 卡片背面颜色,支持纯色和渐变色 |
插槽
| 插槽名 | 说明 | |--------|------| | front | 自定义卡片正面内容,接收index和card参数 | | back | 自定义卡片背面内容,接收index和card参数 |
示例
<!-- 基本用法 -->
<PnFloat
:number="3"
:rotateDuration="15"
/>
<!-- 自定义大小和颜色 -->
<PnFloat
:number="6"
cardWidth="140px"
cardHeight="100px"
:orbitRadius="200"
:rotateDuration="30"
frontColor="linear-gradient(135deg, #ff9a9e 0%, #fad0c4 100%)"
backColor="linear-gradient(135deg, #a1c4fd 0%, #c2e9fb 100%)"
/>
<!-- 自定义卡片内容 -->
<PnFloat
:number="4"
cardWidth="200px"
cardHeight="150px"
:orbitRadius="250"
frontColor="#3498db"
backColor="#2ecc71"
>
<template #front="{ card }">
<div class="custom-card-content">
<h4>正面内容 {{ card }}</h4>
<p>自定义文字内容</p>
</div>
</template>
<template #back="{ card }">
<div class="custom-card-content">
<h4>反面内容 {{ card }}</h4>
<button class="custom-btn">点击按钮</button>
</div>
</template>
</PnFloat>🎯 高级使用示例
1. 自定义样式配置
<template>
<div class="custom-chat-container">
<Pn-chatContainer
width="900px"
height="700px"
backgroundColor="#f5f7fa"
color="#2c3e50"
title="智能问答系统"
apiKey="your_api_key_here"
/>
</div>
</template>
<script setup>
import { PnChatContainer } from 'punine-design'
import 'punine-design/dist/ai-chat-plugin.css'
</script>
<style scoped>
.custom-chat-container {
display: flex;
justify-content: center;
padding: 20px;
}
</style>2. Pn-float组件高级配置
<template>
<div class="float-demo-container">
<!-- 创建一个精美的3D旋转展示区 -->
<PnFloat
:number="8"
cardWidth="160px"
cardHeight="120px"
:orbitRadius="220"
:rotateDuration="35"
radius="20px"
frontColor="linear-gradient(135deg, #84fab0 0%, #8fd3f4 100%)"
backColor="linear-gradient(135deg, #a6c0fe 0%, #f68084 100%)"
>
<template #front="{ card, index }">
<div class="fancy-card-content">
<div class="card-icon">🌟</div>
<h4>特色卡片 {{ card }}</h4>
<p>展示内容 #{{ index + 1 }}</p>
</div>
</template>
<template #back="{ card }">
<div class="fancy-card-content">
<div class="back-icon">💡</div>
<h4>交互区域 {{ card }}</h4>
<button class="action-btn">查看详情</button>
</div>
</template>
</PnFloat>
</div>
</template>
<script setup>
import { PnFloat } from 'punine-design'
import 'punine-design/dist/ai-chat-plugin.css'
</script>
<style scoped>
.float-demo-container {
display: flex;
justify-content: center;
align-items: center;
min-height: 500px;
padding: 20px;
}
.fancy-card-content {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100%;
padding: 15px;
color: white;
text-align: center;
}
.card-icon, .back-icon {
font-size: 28px;
margin-bottom: 10px;
}
.fancy-card-content h4 {
margin: 0 0 8px 0;
font-size: 16px;
}
.fancy-card-content p {
margin: 0;
font-size: 12px;
opacity: 0.9;
}
.action-btn {
margin-top: 12px;
padding: 6px 12px;
background: rgba(255, 255, 255, 0.2);
border: 1px solid rgba(255, 255, 255, 0.4);
border-radius: 20px;
color: white;
font-size: 12px;
cursor: pointer;
transition: all 0.3s ease;
}
.action-btn:hover {
background: rgba(255, 255, 255, 0.3);
transform: translateY(-2px);
}
</style>🔍 常见问题解答
Q: 为什么会出现 "getActivePinia()" 相关的错误?
A: 这是因为Pinia没有被正确初始化或者初始化顺序不正确。请确保在安装聊天插件之前先安装Pinia:
const app = createApp(App)
const pinia = createPinia()
app.use(pinia) // 必须先安装Pinia
app.use(PunineAIChatPlugin) // 然后再安装聊天插件Q: 如何修改组件的默认样式?
A: 有两种方式:
- 使用组件提供的props参数(如backgroundColor、color等)
- 在您的项目中编写自定义CSS来覆盖组件样式
Q: 如何在没有DeepSeek API Key的情况下测试组件?
A: 组件库提供了默认的欢迎消息,但完整功能需要有效的DeepSeek API Key。您可以先使用模拟数据进行UI测试。
Q: 组件支持移动端设备吗?
A: 是的,组件设计考虑了响应式布局,可以适配不同屏幕尺寸的设备。您也可以根据需要通过props调整尺寸。
📄 许可证
MIT License
📧 联系方式
如有问题或建议,请随时联系我们。
