IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> 记一次前端时间埋点基于vue版本的 -> 正文阅读

[JavaScript知识库]记一次前端时间埋点基于vue版本的

埋点(vue)

主要分为4个函数,pageIntevalpageTimelyRecordsetUrlModelFnrecordTrackId。主要依托于路由守卫。主要记录页面时长、最后一个页面的时候、页面的映射路径

pageInteval:主要是用于记录定时任务。说明,因为我们无法记录最后一个页面的时长,故采用将数据记录在localStorage里面,然后通过下一次进入页面的时候发起请求!具体代码如下:

let startTime = Date.now(); // 页面进入的开始时间
let currentTime = null; // 当前时间
let timer = null;
/*页面定时存储,主要记录最后一个页面*/
export const pageInteval = (to, from) => {
    // 当在登入页面
    if(from.path === '/login') {
        const firstAllInfo = JSON.parse(localStorage.getItem('XXX'));
        if(firstAllInfo) {
            axios....// 向后端发起请求
            localStorage.setItem('xxx', null);
            request.setTrackId('-1'); // 页面来源id重新从-1开始
        }
    }
    if(timer) {
        clearInterval(timer);
    }
    const recordStaticInfo = {
        pointUrl: to.path,// 因为是记录最后一个页面所以是to的路径
        pointType: 'page', // 为页面类型
        pointCustomization: JOSN.stringify(to.query) === '{}' : JSON.stringify(to.query)// 页面的附属参数
    }
	
	// 存储任务
	timer = setInterval(async () => {
        // 页面跳转后记录一下当前时间
        currentTime = currentTime - startTime;
        const allInfo = {
            ...recordInfo,
            pointSource: await request.getTrackId(),
            pageStayTime: Math.ceil(diff/1000);
        }
        localStorage.setItem('xxx', JSON.stringify(allInfo));
    }, 5000);
	// 初始化开始日期
	startTime = Date.now();
}

pageTimelyRecordpageInteval 函数类似,pageTimelyRecord 主要是路由路由跳转的时候获取from.path 的情况信息,这边就不再展开去讲了。

setUrlModelFn 主要是记录页面的映射路径,有朋友就要讲了,何为映射路径。那我就要说道说道了。其实也很简单,就是说,你当前页面在第四层级,那么我就要将前面三层的路径也要传给后端,就是 first->second->third->fouth具体代码实现如下。

function setUrlModelFn(direction) {
    // 补齐数组项,如果这边不补齐的化,后面对象查找就会报错, 因为我放的数据是存在路由meta的
    direction.meta.mapPaths = direction.meta.mapPaths || [];
    if(direction.meta.mapPaths.length < 4) {
        // 这里明确确定 这里只有4级菜单
        const sur = 4 - direction.meta.mapPaths.length;
        for(let i = 0; i < sur; i++) {
            // 用于补齐尾项
            direction.meta.mapPaths.push({id:'',name:'',pId: ''});
        }
    }
    const [
        {id: firstMenuId, pId: firstMenuPid},
        {id: secondMenuId, pId: secondMenuPid},
        {id: thirdMenuId, pId: thirdMenuPid},
        {id: fourMenuId, pId: fourMenuPid}
    ] = direction.meta.mapPaths
    // 这一步设置叶子节点菜单和当前叶子菜单的父级
    request.setUrlModel({
        urlLeafId: fourMenuId || thirdMenuId || secondMenuId || firstMenuId,
        urlParentId: fourMenuPid || thirdMenuPid || secondMenuPid || firstMenuPid
    })
}
// 传入to(下一个页面的相关信息,需要配合路由守卫去做)
setUrlModelFn(to);

在这里有一段关键的代码,就是寻找对应的映射路径,这里我单独拿出来,未来也许有需要。看如下代码。

// 获取映射路径
function recordMapPath(array, targetId) {
    const parentSubjectStock = [];// 存储父节点
    let going = true;// 是否已经找到要查找到的节点(false表示已找到不再继续)
    let findParentNode = function(array, id) {
        array.forEach((item) => {
            if(!going) {// 没有找到直接退出
                return
            }
            parentSubjectStock.push(item);
            if(item.id === id) {
                going = false
            } else if(item.children && item.children.length > 0) {
                findParentNode(item.children, id);
            } else {
                // 如果都没找到则剔除当前这一项,以免污染数据
                parentSubjectStock.pop();
            }
        })
        // 剔除一开始就找不到目标id的情况
        if(going) {
            parentSubjectStock.pop();
        }
    }
    findParentNode(array, targetId);
    // 返回自己想要的映射路径
    return parentSubjectStock.map((item) => ({
        id: item.id,
        name: item.name,
        pId: item.pId
    }))
}
/**
	@array 是有层级结构的菜单路径
	@id 对应的菜单叶子节点id
*/
recordMapPath(array, id)

上面这段代码就是说要找到此菜单所对应的菜单路径。

最后说下在路由守卫里面的情况吧,看如下代码和注释。

/*
	在路由前置守卫 beforeEach上面,配合页面跳转权限进行的判断
	
*/
// 如果当前角色在下一个页面有权限
const hasPermision = (role, route) => {
    let meta = route.meta;
    if(meta && meta.roles) return meta.roles.includes(role)
    return true
}
if(hasPermision(role, to)) {
    // 这里避免了在根路径和/login页面的时候发送接口请求
    if(from.path !== '/' && to.path !== '/login') {
        pageInteval(to, from);
    }
    // 这里避免在根路径和在重定向页面去发送接口请求
    if(from.path !== '/' && from.path !== 'redirect/index') {
        pageTimelyRecord(to, from);
    } else {
        next();
    }
}

最后,这边页面时长的埋点算是结束了!其实埋点这个部分非常的有广度,涉及的方方面面,包括页面错误埋点,按钮点击统计,页面跳转路径等等等多方面,未来有机会将会不断的补充和完善此部分的代码。

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-08-19 18:55:10  更:2022-08-19 18:56:32 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 10:15:26-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码