floatball-widget
v0.1.0
Published
Floating chat widget as Web Component
Readme
Floatball 集成文档(React / Vue)
本文说明如何在 React 应用和 Vue 应用中集成 floatball 悬浮球聊天组件。
1. 组件能力说明
- 悬浮球通过 React 渲染,支持拖拽、点击打开聊天窗。
- 聊天窗支持流式消息、历史会话、附件选择。
- 支持通过运行时注入方式配置接口信息(推荐,且可避免敏感信息进入 dist)。
2. 运行时配置(推荐,适用于对外分发 dist)
2.1 通过全局变量注入(推荐)
在加载/初始化浮球之前设置:
window.__FLOATBALL_WIDGET_CONFIG__ = {
proxyApiUrl: 'https://your-host/v1/chat-messages',
apiKey: 'app-xxxxxxxxxxxxxxxx',
}
apiKey属于敏感信息:不要写死在源码里,也不要在构建时通过环境变量注入到 dist。
2.2 通过元素属性注入(简单)
<floatball-widget
api-url="https://your-host/v1/chat-messages"
api-key="app-xxxxxxxxxxxxxxxx"
></floatball-widget>3. 对外发布接入(npm 包:floatball-widget)
下面是外部企业在其项目中接入已编译产物(dist)的最小步骤:不需要导入 src,只需引入 npm 包并使用 <floatball-widget /> 标签即可。
3.1 安装包
npm i floatball-widget3.2 在应用入口加载一次(完成 custom element 注册)
在宿主项目的入口文件(例如 main.js/main.ts 或 index.tsx)增加:
import 'floatball-widget'注意:仅在页面里写
<floatball-widget />可能不会自动注册元素;务必在入口import 'floatball-widget'。
3.3 注入运行时配置(建议在 import 之前)
方式 A:全局变量注入(推荐)
在入口文件尽早加入:
window.__FLOATBALL_WIDGET_CONFIG__ = {
proxyApiUrl: 'https://your-host/v1/chat-messages',
apiKey: 'app-xxxxxxxxxxxxxxxx',
}
import 'floatball-widget'方式 B:元素属性注入(简单)
<floatball-widget
api-url="https://your-host/v1/chat-messages"
api-key="app-xxxxxxxxxxxxxxxx"
></floatball-widget>
apiKey属于敏感信息:如可行,建议由你们后端侧做鉴权/代理,前端仅拿短期 token 或会话标识。
3.4 Vue / React 页面使用
Vue(任意版本,只要支持 Web Components 标签即可):
<floatball-widget />React:
return <floatball-widget />3.5 Vue2(Webpack)补充:忽略自定义元素警告
在入口(main.js)中加入:
import Vue from 'vue'
Vue.config.ignoredElements = ['floatball-widget']
import 'floatball-widget'3.6 Vue3(Vite)补充:声明自定义元素
// build/plugin/index.js
vue({
template: {
compilerOptions: {
isCustomElement: (tag) => tag.startsWith('floatball-'),
},
},
})4. Vue 应用集成(推荐使用 Web Component,源码接入/调试示例)
4.1 在入口注册自定义元素
在 src/main.js 中引入一次:
import '../floatball/src/web-component'4.2 在页面中直接使用标签
在 src/App.vue(或任意页面)中加入:
<floatball-widget />4.3 Vite 配置(必须)
如果是 Vue + Vite,需要告诉编译器这是自定义元素,否则会被当成 Vue 组件解析:
// build/plugin/index.js
vue({
template: {
compilerOptions: {
isCustomElement: (tag) => tag.startsWith('floatball-'),
},
},
})5. Vue2(Webpack)最小接入示例(源码接入/调试示例)
如果你的宿主项目是 Vue2 + Webpack,推荐同样用 Web Component 方式接入。
5.1 入口引入(src/main.js)
import Vue from 'vue'
import App from './App.vue'
// 告诉 Vue2:floatball-widget 是自定义元素,不当作 Vue 组件解析
Vue.config.ignoredElements = ['floatball-widget']
// 注册 floatball 自定义元素(路径按你的项目实际位置调整)
import '../floatball/src/web-component'
new Vue({
render: (h) => h(App),
}).$mount('#app')5.2 页面使用(src/App.vue)
<template>
<div id="app">
<h1>Vue2 页面</h1>
<floatball-widget />
</div>
</template>5.3 可选:老浏览器 polyfill
如果需要兼容不支持 Web Components 的老浏览器(例如 IE),请额外引入 polyfill。
npm i @webcomponents/webcomponentsjs然后在入口尽早引入:
import '@webcomponents/webcomponentsjs/webcomponents-bundle'6. React 应用集成(源码接入/调试示例)
React 中有两种方式:Web Component 方式和 JS API 方式。
6.1 方式 A:Web Component(简单,推荐)
在应用入口(如 src/main.tsx 或 src/index.tsx)引入注册文件:
import '../floatball/src/web-component'在页面中使用:
export default function Page() {
return <floatball-widget />
}如果是 TypeScript,建议补充自定义元素声明(避免 TS 报错):
declare global {
namespace JSX {
interface IntrinsicElements {
'floatball-widget': React.DetailedHTMLProps<
React.HTMLAttributes<HTMLElement>,
HTMLElement
>
}
}
}6.2 方式 B:JS API(需要手动控制生命周期)
floatball/src/index.ts 暴露了四个方法:
init():创建并挂载浮球open():打开聊天窗口close():关闭聊天窗口destroy():销毁浮球
React 示例:
import { useEffect } from 'react'
import { init, destroy } from '../floatball/src'
export default function App() {
useEffect(() => {
init()
return () => destroy()
}, [])
return <div>your page</div>
}7. 常见问题排查
7.1 页面没有看到悬浮球
优先检查:
- 是否已在入口执行
import 'floatball-widget'(或内部调试时的web-component注册文件) - 页面中是否真的渲染了
<floatball-widget /> - Vue 项目是否配置了
isCustomElement - React 版本是否使用
createRoot挂载(当前代码已适配) - 控制台是否有运行时错误(如环境变量、接口跨域等)
7.2 报错 process is not defined
浏览器端应使用 import.meta.env,不要使用 process.env。
7.4 报错 “未配置 Floatball API_KEY”
这是预期行为:为避免敏感信息进入 dist,组件不会内置 apiKey。
请按本文第 2 节通过 window.__FLOATBALL_WIDGET_CONFIG__ 或元素属性注入。
7.3 样式被宿主应用影响
浮球主体运行在 Shadow DOM 内,一般不会被外部污染;聊天弹层通过 portal 挂到 document.body,若视觉异常,重点检查宿主全局样式(z-index、transform、overflow)。
8. 推荐接入方式
- Vue 项目:优先用
Web Component - React 项目:也优先
Web Component,只有在需要更强控制时再改用JS API
这样可保持接入路径一致、维护成本最低。
