埋点(vue )
主要分为4个函数,pageInteval 、pageTimelyRecord 、setUrlModelFn 、recordTrackId 。主要依托于路由守卫。主要记录页面时长、最后一个页面的时候、页面的映射路径
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');
}
}
if(timer) {
clearInterval(timer);
}
const recordStaticInfo = {
pointUrl: to.path,
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();
}
pageTimelyRecord 与 pageInteval 函数类似,pageTimelyRecord 主要是路由路由跳转的时候获取from.path 的情况信息,这边就不再展开去讲了。
setUrlModelFn 主要是记录页面的映射路径,有朋友就要讲了,何为映射路径。那我就要说道说道了。其实也很简单,就是说,你当前页面在第四层级,那么我就要将前面三层的路径也要传给后端,就是 first->second->third->fouth 具体代码实现如下。
function setUrlModelFn(direction) {
direction.meta.mapPaths = direction.meta.mapPaths || [];
if(direction.meta.mapPaths.length < 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
})
}
setUrlModelFn(to);
在这里有一段关键的代码,就是寻找对应的映射路径,这里我单独拿出来,未来也许有需要。看如下代码。
function recordMapPath(array, targetId) {
const parentSubjectStock = [];
let going = true;
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();
}
})
if(going) {
parentSubjectStock.pop();
}
}
findParentNode(array, targetId);
return parentSubjectStock.map((item) => ({
id: item.id,
name: item.name,
pId: item.pId
}))
}
recordMapPath(array, id)
上面这段代码就是说要找到此菜单所对应的菜单路径。
最后说下在路由守卫里面的情况吧,看如下代码和注释。
const hasPermision = (role, route) => {
let meta = route.meta;
if(meta && meta.roles) return meta.roles.includes(role)
return true
}
if(hasPermision(role, to)) {
if(from.path !== '/' && to.path !== '/login') {
pageInteval(to, from);
}
if(from.path !== '/' && from.path !== 'redirect/index') {
pageTimelyRecord(to, from);
} else {
next();
}
}
最后,这边页面时长的埋点算是结束了!其实埋点这个部分非常的有广度,涉及的方方面面,包括页面错误埋点,按钮点击统计,页面跳转路径等等等多方面,未来有机会将会不断的补充和完善此部分的代码。
|