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

vue项目进行前端埋点,记录页面菜单停留时间

主要采用代码埋点,分为以下两点:

  • 命令式埋点
  • 声明式埋点

一、命令式埋点

命令式埋点,顾名思义,开发者需要手动在需要埋点的节点处进行埋点。如点击按钮或链接后的回调函数、页面ready时进行请求的发送。

// 页面加载时发送埋点请求
$(document).ready(function(){
   // ... 这里存在一些业务逻辑
   sendRequest(params);
});
// 按钮点击时发送埋点请求
$('button').click(function(){
   // ... 这里存在一些业务逻辑
   sendRequest(params);
});

可以很容易发现,这样的做法很有可能会将埋点代码侵入业务代码,这使整体业务代码变得繁琐,容易出错,且后续代码会愈加膨胀,难以维护。所以,我们需要让埋点的代码与具体的业务逻辑解耦,即 声明式埋点 ,从而提高埋点的效率和代码的可维护性。

二、声明式埋点

点击埋点:自定义指令实现统计用户在应用内的每一次点击事件,如新闻的浏览次数、文件下载的次数、推荐商品的命中次数等。

在项目入口文件 main.js 中配置我们的自定义指令

Vue.directive('log', {
  bind(el, binding) {
    el.addEventListener('click', () => {
       Axios.post  //发送请求
    }, false);
  }
});

组件中配置使用v-log指令,加上详情参数就可以完成用户轨迹记录。

// caption表示埋点的模块;paras表示用户的行为
<button v-log="{caption:'登录页', paras: '用户点击验证码发送'}">发送验证码</button>

页面埋点:统计用户进入或离开页面的各种维度信息,如页面浏览次数(PV)、浏览页面人数(UV)、页面停留时间、浏览器信息等。

使用 vue-router 的 beforeEach 或者 afterEach 钩子上报数据,具体使用哪个最好是根据业务逻辑来选择。

/**页面埋点方案*/
let startTime = Date.now();
let currentTime;
router.beforeEach((to, from, next) => {
  if (to) {
    // 第一步:页面跳转后记录一下当前的时间 currentTime
    currentTime = Date.now();
    // 第二步:计算 currentTime - startTime 的 差值
    const user = JSON.parse(localStorage.getItem("sysUser"));
    const log = {
      当前用户: user.userId,
      当前页路由: from.name,
      当前页菜单名: from.name,
      目标页: to.name,
      开始时间: startTime,
      结束时间: currentTime,
      // "停留时间(ms)": currentTime - startTime,
      "停留时间(s)": parseInt((currentTime - startTime) / 1000),
    };
    console.table(log, "log");
    // 第三步:每次都要初始化一下 startTime
    startTime = Date.now();
  }
  next();
});

 

相关文章:

  • input实现在移动端软键盘中显示“搜索”案件的注意事项
  • export, import 的用法详解
  • vue中ref的作用及用法
  • Vue中数据缓存localStroage
  • keep-alive实现数据缓存
  • keep-alive的使用
  • Vue项目中文件路径的引用问题
  • e.preventDefault()与e.stopPropagation()的区别
  • es6数组方法find()、findIndex()与filter()的总结
  • js数组对象(1个数组) 判断 | 两个属性值相同时,另外某个属性值相加
  • js数组对象去重(4种方法)
  • js数组对象 判断两个属性值相同时另外某个属性值相加后,再进行 去重 (项目实战提取!!!)
  • Vue2.0 $set()的正确使用详解
  • Vue的三个点es6知识,扩展运算符
  • js中forEach()和map()的区别和理解
  • 【399天】跃迁之路——程序员高效学习方法论探索系列(实验阶段156-2018.03.11)...
  • 【划重点】MySQL技术内幕:InnoDB存储引擎
  • gf框架之分页模块(五) - 自定义分页
  • Iterator 和 for...of 循环
  • Making An Indicator With Pure CSS
  • 计算机常识 - 收藏集 - 掘金
  • 快速构建spring-cloud+sleuth+rabbit+ zipkin+es+kibana+grafana日志跟踪平台
  • 罗辑思维在全链路压测方面的实践和工作笔记
  • 模型微调
  • 前端
  • 数据结构java版之冒泡排序及优化
  • 体验javascript之美-第五课 匿名函数自执行和闭包是一回事儿吗?
  • 限制Java线程池运行线程以及等待线程数量的策略
  • Prometheus VS InfluxDB
  • 如何在招聘中考核.NET架构师
  • ​软考-高级-系统架构设计师教程(清华第2版)【第20章 系统架构设计师论文写作要点(P717~728)-思维导图】​
  • ​香农与信息论三大定律
  • #WEB前端(HTML属性)
  • (附源码)ssm户外用品商城 毕业设计 112346
  • (附源码)计算机毕业设计SSM疫情居家隔离服务系统
  • (七)理解angular中的module和injector,即依赖注入
  • (一)UDP基本编程步骤
  • (转)Android学习系列(31)--App自动化之使用Ant编译项目多渠道打包
  • (轉貼) 2008 Altera 亞洲創新大賽 台灣學生成果傲視全球 [照片花絮] (SOC) (News)
  • .NET 同步与异步 之 原子操作和自旋锁(Interlocked、SpinLock)(九)
  • .NET/C# 在代码中测量代码执行耗时的建议(比较系统性能计数器和系统时间)...
  • .net开源工作流引擎ccflow表单数据返回值Pop分组模式和表格模式对比
  • .NET学习教程二——.net基础定义+VS常用设置
  • 。Net下Windows服务程序开发疑惑
  • [ C++ ] STL---string类的使用指南
  • [ solr入门 ] - 利用solrJ进行检索
  • [ vulhub漏洞复现篇 ] Django SQL注入漏洞复现 CVE-2021-35042
  • [120_移动开发Android]008_android开发之Pull操作xml文件
  • [ARC066F]Contest with Drinks Hard
  • [bzoj 3534][Sdoi2014] 重建
  • [codeforces]Levko and Permutation
  • [codeforces]Recover the String
  • [CTSC2014]企鹅QQ
  • [docker] Docker的数据卷、数据卷容器,容器互联
  • [EFI]Dell Latitude-7400电脑 Hackintosh 黑苹果efi引导文件