当前位置: 首页 > news >正文

auto-tracking自动埋点插件

自动埋点插件使用说明

概述

auto-tracking.js 是一个 Vue 插件,用于自动为页面上的所有按钮添加埋点标识,无需手动在每个按钮上添加 v-tracking 指令或 data-warden-title 属性。

功能特性

  • 完全自动化:无需手动配置,自动为所有按钮添加埋点
  • 智能识别:根据按钮文本自动推断操作类型
  • 路由集成:自动获取路由 meta.title 作为模块名
  • 优先级保护:如果按钮已手动设置埋点,则跳过自动处理
  • 动态支持:支持动态添加的按钮(通过 MutationObserver)
  • 路由响应:路由切换时自动更新埋点标识

安装使用

1. 插件已在 main.js 中注册

import autoTracking from '@/plugins/auto-tracking';
Vue.use(autoTracking);

2. 无需任何额外配置

插件会自动工作,为所有 el-button 按钮自动添加埋点。

使用示例

基础用法

之前需要手动添加埋点:

<!-- 之前:需要手动添加 -->
<el-button v-tracking="'query'" @click="handleQuery">查询</el-button>
<el-button:data-warden-title="'用户管理-导出'"@click="handleExport"
>导出</el-button>

现在完全不需要:

<!-- 现在:自动添加埋点 -->
<el-button @click="handleQuery">查询</el-button>
<el-button @click="handleExport">导出</el-button>

插件会自动生成埋点标识:

  • 查询 按钮 → 当前页面title-查询
  • 导出 按钮 → 当前页面title-导出

保留手动配置

如果某个按钮需要手动指定埋点标识,可以继续使用手动方式,插件会跳过自动处理:

<!-- 手动设置,插件不会覆盖 -->
<el-button:data-warden-title="'用户管理-自定义查询'"@click="handleQuery"
>查询</el-button>
<el-buttonv-tracking="{ action: 'export', module: '自定义模块' }"@click="handleExport"
>导出</el-button>

排除某些按钮

如果某个按钮不需要埋点,可以添加 data-no-tracking 属性:

<!-- 排除埋点 -->
<el-button data-no-tracking @click="handleCancel">取消</el-button>

自动识别的操作类型

插件内置了常见按钮文本到操作类型的映射:

按钮文本操作类型
查询、搜索查询
导出导出
下载下载
删除、移除删除
新增、添加、创建新增
编辑、修改、更新修改
同步同步
刷新刷新
重置、清空重置
导入、上传导入
启动、开始启动
暂停、停止暂停
保存、确认、提交保存
取消、关闭取消
查看、详情查看
复制复制
打印打印

埋点标识格式

自动生成的埋点标识格式为:

{路由meta.title}-{操作类型}

例如:

  • 路由 title 为 用户管理,按钮文本为 查询用户管理-查询
  • 路由 title 为 系统配置,按钮文本为 新增系统配置-新增

注意事项

  1. 路由配置:确保路由配置中包含 meta.title,否则会使用 未知页面 作为模块名
  2. 国际化支持:如果按钮文本使用了国际化($t()),插件会自动识别
  3. 动态按钮:插件支持动态添加的按钮,会自动为其添加埋点
  4. 性能:使用防抖机制,避免频繁触发,不会影响页面性能

工作原理

  1. 插件在 Vue 实例挂载时自动运行
  2. 使用 MutationObserver 监听 DOM 变化
  3. 为所有 .el-button 元素自动添加 data-warden-title 属性
  4. 如果元素已有 data-warden-title 或使用了 v-tracking,则跳过
  5. 路由切换时,自动更新所有按钮的埋点标识

与现有方案兼容

  • ✅ 与 v-tracking 指令完全兼容(手动设置的优先级更高)
  • ✅ 与 TrackButton 组件兼容(组件内部已设置埋点的不会被覆盖)
  • ✅ 与手动设置的 data-warden-title 兼容

排除规则

以下按钮会被自动排除:

  • 已有 data-warden-title 属性的按钮
  • 使用了 v-tracking 指令的按钮
  • data-no-tracking 属性的按钮
  • 分页组件中的按钮
  • 对话框关闭按钮
  • 消息框按钮
/*** 自动埋点插件* 无需手动在按钮上添加埋点信息,自动根据按钮文本和路由信息生成埋点标识** 功能:* 1. 自动为所有 el-button 按钮添加埋点* 2. 根据按钮文本自动推断操作类型* 3. 自动获取路由 title 作为模块名* 4. 如果按钮已手动设置了 data-warden-title 或使用了 v-tracking,则跳过自动处理** 使用方式:* 在 main.js 中引入并注册:Vue.use(autoTracking)*/// 按钮文本到操作类型的映射
const TEXT_TO_ACTION = {// 基础操作查询: '查询',搜索: '查询',导出: '导出',下载: '下载',删除: '删除',移除: '删除',新增: '新增',添加: '新增',创建: '新增',编辑: '修改',修改: '修改',更新: '修改',同步: '同步',刷新: '刷新',重置: '重置',清空: '重置',导入: '导入',上传: '导入',启动: '启动',开始: '启动',暂停: '暂停',停止: '暂停',保存: '保存',确认: '保存',提交: '保存',取消: '取消',关闭: '取消',查看: '查看',详情: '查看',复制: '复制',打印: '打印',// 扩展操作批量删除: '批量删除',批量导出: '批量导出',批量导入: '批量导入',批量操作: '批量操作',一键采集: '一键采集',采集: '采集',获取: '获取',审批: '审批',拒绝: '拒绝',订阅: '订阅',取消订阅: '取消订阅',
};// 需要排除的选择器(避免对不需要埋点的按钮添加)
const EXCLUDE_SELECTORS = ['el-pagination .el-button', // 分页按钮'el-dialog__headerbtn', // 对话框关闭按钮'.el-message-box__btns .el-button', // 消息框按钮'[data-no-tracking]', // 手动标记不需要埋点的元素
];// 判断元素是否应该被排除
function shouldExclude(element) {if (!element) return true;// 检查是否已有手动设置的埋点if (element.hasAttribute('data-warden-title')) {return true;}// 检查是否使用了 v-tracking 指令(Vue会添加这个属性)if (element.__v_tracking || element.getAttribute('v-tracking')) {return true;}// 检查排除选择器for (const selector of EXCLUDE_SELECTORS) {if (element.closest(selector)) {return true;}}// 检查是否有 data-no-tracking 属性if (element.hasAttribute('data-no-tracking')) {return true;}return false;
}// 获取按钮文本
function getButtonText(element, vueInstance) {// 获取按钮的所有文本内容let text = element.textContent?.trim() || element.innerText?.trim() || '';// 清理文本:移除多余的空白字符text = text.replace(/\s+/g, ' ').trim();// 如果有 Vue 实例,尝试使用国际化if (vueInstance && vueInstance.$t && text) {try {// 尝试将文本作为国际化键const i18nText = vueInstance.$t(text);if (i18nText && i18nText !== text) {text = i18nText;}} catch (e) {// 忽略错误,继续使用原始文本}}return text;
}// 生成埋点标识
function generateTrackingTitle(buttonText, routeTitle) {if (!buttonText) return '';// 从按钮文本推断操作类型const action = TEXT_TO_ACTION[buttonText] || buttonText;// 生成埋点标识:路由title-操作类型return `${routeTitle}-${action}`;
}// 自动为按钮添加埋点
function addAutoTracking(element, vueInstance) {if (shouldExclude(element)) {return;}const buttonText = getButtonText(element, vueInstance);if (!buttonText) {return;}// 获取路由 titleconst routeTitle =vueInstance?.$router?.currentRoute?.meta?.title || '未知页面';// 生成埋点标识const trackingTitle = generateTrackingTitle(buttonText, routeTitle);if (trackingTitle) {element.setAttribute('data-warden-title', trackingTitle);}
}// 使用 MutationObserver 监听 DOM 变化,自动为新添加的按钮添加埋点
function setupMutationObserver(vueInstance) {// 使用防抖,避免频繁触发let timeout = null;const processNodes = (nodes) => {clearTimeout(timeout);timeout = setTimeout(() => {nodes.forEach((node) => {if (node.nodeType === 1) {// Element node// 检查是否是按钮if (node.classList && node.classList.contains('el-button')) {vueInstance.$nextTick(() => {addAutoTracking(node, vueInstance);});}// 检查子元素中的按钮if (node.querySelectorAll) {const buttons = node.querySelectorAll('.el-button');buttons.forEach((button) => {vueInstance.$nextTick(() => {addAutoTracking(button, vueInstance);});});}}});}, 100); // 延迟100ms执行,等待Vue渲染完成};const observer = new MutationObserver((mutations) => {const addedNodes = [];mutations.forEach((mutation) => {mutation.addedNodes.forEach((node) => {addedNodes.push(node);});});if (addedNodes.length > 0) {processNodes(addedNodes);}});observer.observe(document.body, {childList: true,subtree: true,});return observer;
}// 为现有按钮添加埋点
function trackExistingButtons(vueInstance) {// 延迟执行,确保 Vue 实例已完全初始化vueInstance.$nextTick(() => {const buttons = document.querySelectorAll('.el-button');buttons.forEach((button) => {addAutoTracking(button, vueInstance);});});
}export default {install(Vue) {// 在 Vue 实例创建后自动添加埋点Vue.mixin({mounted() {// 只在根组件执行一次if (this.$root === this) {// 为现有按钮添加埋点trackExistingButtons(this);// 设置 MutationObserver 监听新添加的按钮this._autoTrackingObserver = setupMutationObserver(this);// 监听路由变化,更新埋点(因为模块名可能改变)if (this.$router) {this.$router.afterEach(() => {this.$nextTick(() => {const buttons = document.querySelectorAll('.el-button');buttons.forEach((button) => {// 只更新没有手动设置的按钮if (!button.hasAttribute('data-warden-title') &&!button.hasAttribute('data-no-tracking')) {addAutoTracking(button, this);}});});});}}},beforeDestroy() {// 清理 MutationObserverif (this.$root === this && this._autoTrackingObserver) {this._autoTrackingObserver.disconnect();}},});},
};
http://www.dtcms.com/a/566128.html

相关文章:

  • 什么叫网站维护建购物网站难吗
  • 公司做网页要多少钱佛山seo
  • 美术馆网站建设概述网站如何收录快
  • 避免出现重复的属性方法:Python高级编程技巧详解
  • 营销型网站建设的五力原则包括深圳在线官网
  • 德州口碑好的网站制作公司爱站网关键词挖掘工具熊猫
  • 响应式外贸网站价格著名的wordpress网站
  • 【每日一面】实现一个深拷贝函数
  • 图标网站导航制作怎么做网站后台管理系统设计
  • 产品月报|睿本云10月产品功能迭代
  • 国外物流公司网站模板长沙专业网站制作
  • 河北邯郸建网站流量平台
  • 【文献分享】利用 GeneTEA 对基因描述进行自然语言处理以进行过表达分析
  • 开发笔记之:python集成Qt C++编写的扩展模块
  • 新野网站建设旅行社手机网站建设方案
  • 乌兰察布市建设局网站淮安网站建设推广
  • 查看数据库表某一段时间的镜像
  • 三目运算符
  • 做兼职编辑的网站网站建设配图
  • 数组——定长滑动窗口:1343. 大小为 K 且平均值大于等于阈值的子数组数目
  • Linux如何根据一个服务端口查询是二进制还是Docker容器安装
  • Ubuntu虚拟机部署Dify+Ollama搭建智能体和工作流
  • 在百度建免费网站吗网站开发总结报告
  • 【C + +】C++11 (下) | 类新功能 + STL 变化 + 包装器全解析
  • Linux的lsblk、fdisk和gdisk
  • 企业级业务平台项目设计、架构、业务全解之平台篇
  • 玩客云做网站建设网站的网站首页
  • 淘宝客导购网站怎么做运营推广seo招聘
  • 第一次全国水利普查公报的土壤保持部分
  • 爬虫数据清洗可视化链家房源