• 记一次前端时间埋点基于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();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    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);
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

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

    // 获取映射路径
    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)
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

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

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

    /*
    	在路由前置守卫 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();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

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

  • 相关阅读:
    Verilog 条件语句
    使用jsch和commons-pool2为sftp创建连接池
    《Python+Kivy(App开发)从入门到实践》自学笔记:高级UX部件——Bubble气泡
    Docker之数据卷&自定义镜像
    全向相机模型Omnidirectional Camera Model
    使用IntelliJ Idea开发Spark Streaming流应用程序
    学弟:功能测试转测试开发容易吗?
    Springboot如何实现数据预热
    Redis 一个key-value存储系统
    户外骑行运动耳机哪个好,几款适合在骑行佩戴的耳机推荐
  • 原文地址:https://blog.csdn.net/qq_38588845/article/details/126370882