watch-tower-vue
v1.0.0
Published
A Vue3 plugin for session recording and performance monitoring using RRWeb
Maintainers
Readme
Watch Tower Vue
一个基于 RRWeb 的 Vue3 插件,用于录制和回放用户会话,帮助你更好地理解用户行为和调试问题。
特性
- 完整的用户会话录制(点击、输入、滚动等)
- 支持 Canvas 录制
- 控制台日志录制
- Vue3 组合式 API(Composables)
- TypeScript 类型支持
- 灵活的配置选项
- 自动或手动录制模式
- 导出录制数据
安装
npm install watch-tower-vue
# 或
yarn add watch-tower-vue
# 或
pnpm add watch-tower-vue基本使用
1. 作为 Vue 插件使用
在 main.js 或 main.ts 中:
import { createApp } from 'vue';
import App from './App.vue';
import WatchTower from 'watch-tower-vue';
const app = createApp(App);
// 安装插件
app.use(WatchTower, {
maxDuration: 10 * 60 * 1000, // 最大录制时长 10 分钟
recordCanvas: true, // 录制 Canvas
collectFonts: true, // 收集字体
recordLog: true, // 录制控制台日志
autoStart: false, // 不自动开始录制
});
app.mount('#app');2. 在组件中使用 Composables API
<template>
<div>
<h1>Watch Tower Demo</h1>
<div class="controls">
<button @click="startRecording" :disabled="isRecording">
开始录制
</button>
<button @click="stopRecording" :disabled="!isRecording">
停止录制
</button>
<button @click="saveToLocalStorage" :disabled="isRecording">
保存录制
</button>
<button @click="exportToFile" :disabled="isRecording">
导出文件
</button>
</div>
<div class="stats">
<p>录制状态: {{ isRecording ? '录制中' : '已停止' }}</p>
<p>录制时长: {{ formattedDuration }}</p>
<p>事件数量: {{ eventCount }}</p>
</div>
</div>
</template>
<script setup>
import { useRecorder } from 'watch-tower-vue';
const {
isRecording,
eventCount,
formattedDuration,
startRecording,
stopRecording,
saveToLocalStorage,
exportToFile,
} = useRecorder();
</script>3. 使用全局属性
在选项式 API 中:
<script>
export default {
mounted() {
// 通过 this.$recorder 访问
this.$recorder.startRecording({
maxDuration: 5 * 60 * 1000,
});
},
beforeUnmount() {
this.$recorder.stopRecording();
}
}
</script>4. 直接使用 Recorder 类
import { RRwebRecorder } from 'watch-tower-vue';
const recorder = new RRwebRecorder({
maxDuration: 5 * 60 * 1000,
recordCanvas: true,
});
// 开始录制
recorder.startRecording();
// 停止录制
const events = recorder.stopRecording();
// 保存到 localStorage
recorder.saveToLocalStorage('my-recording');
// 导出为文件
recorder.exportToFile('recording.json');配置选项
interface RecorderOptions {
maxDuration?: number; // 最大录制时长(毫秒),默认 5 分钟
collectAllData?: boolean; // 是否收集所有数据,默认 true
recordCanvas?: boolean; // 是否录制 canvas,默认 true
collectFonts?: boolean; // 是否收集字体,默认 true
recordLog?: boolean; // 是否录制控制台日志,默认 true
autoStart?: boolean; // 是否自动开始录制,默认 false
onEventEmit?: (event) => void; // 事件触发回调
}API 参考
useRecorder()
返回一个包含以下属性和方法的对象:
响应式状态
isRecording: Ref<boolean>- 是否正在录制events: Ref<any[]>- 事件列表eventCount: Ref<number>- 事件数量recordingDuration: Ref<number>- 录制时长(秒)formattedDuration: Ref<string>- 格式化的时长 (mm:ss)
方法
startRecording(options?)- 开始录制stopRecording()- 停止录制,返回事件列表saveToLocalStorage(key?)- 保存到 localStorageexportToFile(filename?)- 导出为 JSON 文件clearEvents()- 清空事件getEvents()- 获取事件列表
RRwebRecorder 类
实例方法
startRecording(options?)- 开始录制stopRecording()- 停止录制getEvents()- 获取事件列表getRecordingStatus()- 获取录制状态clearEvents()- 清空事件saveToLocalStorage(key?)- 保存到 localStorageexportToFile(filename?)- 导出为文件reportEvent(event)- 上报单个事件
静态方法
RRwebRecorder.loadFromLocalStorage(key?)- 从 localStorage 加载RRwebRecorder.clearLocalStorage(key?)- 清除 localStorage
高级用法
自定义事件回调
app.use(WatchTower, {
onEventEmit: (event) => {
console.log('录制事件:', event);
// 可以在这里实时上报到服务器
fetch('/api/recording/event', {
method: 'POST',
body: JSON.stringify(event),
});
}
});条件录制
import { useRecorder } from 'watch-tower-vue';
const { startRecording } = useRecorder();
// 只在出现错误时开始录制
window.addEventListener('error', () => {
startRecording({
maxDuration: 2 * 60 * 1000, // 错误发生后录制 2 分钟
});
});与路由集成
import { useRecorder } from 'watch-tower-vue';
import { useRouter } from 'vue-router';
const router = useRouter();
const { startRecording, stopRecording, saveToLocalStorage } = useRecorder();
// 每次路由变化时保存录制
router.afterEach(() => {
if (isRecording.value) {
stopRecording();
saveToLocalStorage();
startRecording(); // 开始新的录制
}
});回放录制内容
要回放录制的内容,你需要使用 rrweb-player:
npm install rrweb-player<template>
<div ref="playerContainer"></div>
</template>
<script setup>
import { ref, onMounted } from 'vue';
import rrwebPlayer from 'rrweb-player';
import 'rrweb-player/dist/style.css';
import { RRwebRecorder } from 'watch-tower-vue';
const playerContainer = ref(null);
onMounted(() => {
// 从 localStorage 加载录制数据
const data = RRwebRecorder.loadFromLocalStorage();
if (data && playerContainer.value) {
new rrwebPlayer({
target: playerContainer.value,
props: {
events: data.events,
width: 1024,
height: 768,
},
});
}
});
</script>浏览器兼容性
- Chrome >= 60
- Firefox >= 55
- Safari >= 11
- Edge >= 79
注意事项
- 录制数据可能会很大,建议设置合理的
maxDuration - 敏感信息(如密码)默认会被屏蔽
- localStorage 有存储限制(通常 5-10MB)
- 生产环境建议将录制数据上传到服务器而不是保存在本地
License
ISC
贡献
欢迎提交 Issue 和 Pull Request!
