vue專案埋點之指令埋點(點選和曝光)
阿新 • • 發佈:2020-07-23
埋點方案有命令式埋點和宣告式埋點。
- 命令式埋點:在使用者行為觸發位置呼叫事件上報函式進行行為上報,缺點是埋點和業務耦合度比較高,工作量比較大
- 宣告式埋點:通過自定義指令統一完成事件上報,使得埋點和業務程式碼一定程度上解耦合。
本篇文章將記錄藉助vue自定義指令完成宣告式埋點,降低前端埋點壓力。
一、準備工作
這裡關於vue自定義指令和IntersectionObserver不做詳細介紹,自行前往官網瞭解學習。
- vue自定義指令,vue自定義指令官網
- IntersectionObserver實現元素視窗觀測,Intersection Observer API
二、程式碼實現
- 建立指令
這裡我們計劃建立v-track
import Vue from 'vue' import Exposure from './exposure' import Click from './click' // 例項化曝光和點選 const exp = new Exposure() const cli = new Click() Vue.directive('track', { // 呼叫指令宣告週期鉤子函式bind,其他鉤子函式請移步官網 bind(el, binding) { // 獲取指令引數 const { arg } = binding arg.split('|').forEach(item => { // 點選 if (item === 'click') { cli.add({ el }) } else if (item === 'exposure') { exp.add({ el }) } }) } })
- 曝光類
exposure.js
曝光使用IntersectionObserver觀察元素是否在視窗內,並且曝光上報只上報一次,上報之後移除觀察。設定每2秒進行一次上報。
如何解決曝光的漏報(定時器2秒之內的使用者退出)和多報:
a. 漏報:儲存localStorage,下次進入之後如果有資料則上報,如果使用者再不進入,對漏報的幾條資料可忽略
b. 多報:IntersectionObserver監聽曝光,上報時候移除元素的監聽
import 'intersection-observer' import { track } from './sendData' // 節流時間調整,預設100ms IntersectionObserver.prototype['THROTTLE_TIMEOUT'] = 300 export default class Exposure { constructor(maxNum = 20) { this.cacheDataArr = [] this.maxNum = maxNum this._timer = 0 this._observer = null this.init() } /** * 初始化 */ init() { const self = this // 邊界處理 this.trackFromLocalStorage() this.beforeLeaveWebview() // 例項化監聽 this._observer = new IntersectionObserver(function(entries, observer) { entries.forEach((entry) => { // 出現在視窗中 if (entry.isIntersecting) { // 清除當前定時器 clearInterval(this._timer) // 獲取引數 const tp = entry.target.attributes['track-params'].value // 收集引數統一上報,減少網路請求 self.cacheDataArr.push(tp) // 曝光之後取消觀察 self._observer.unobserve(entry.target) if (self.cacheDataArr.length >= self.maxNum) { self.track() } else { self.storeIntoLocalStorage(self.cacheDataArr) if (self.cacheDataArr.length > 0) { // 2秒上報一次 self._timer = setInterval(function() { self.track() }, 2000) } } } }) }, { root: null, rootMargin: '0px', threshold: 0.5 // 元素出現面積,0 - 1,這裡當元素出現一半以上則進行曝光 }) } /** * 給元素新增監聽 * @param {Element} entry */ add(entry) { this._observer && this._observer.observe(entry.el) } /** * 埋點上報 */ track() { const trackData = this.cacheDataArr.splice(0, this.maxNum) track(trackData) // 更新localStoragee this.storeIntoLocalStorage(this.cacheDataArr) } /** * 儲存到localstorage, 防止在設定上報時間內使用者退出 * @param { Arrary } data */ storeIntoLocalStorage(data) { window.localStorage.setItem('cacheTrackData', data) } /** * 首次進入先獲取localStorage中的資料,也就是使用者上次退出未上報的資料 */ trackFromLocalStorage() { const cacheData = window.localStorage.getItem('cacheTrackData') if (cacheData) { track(cacheData) } } /** * 使用者退出系統時呼叫方法,需要和客戶端同學協商註冊事件 */ beforeLeaveWebview() { // 客戶端自定義事件監聽上報 } }
- 點選類
click.js
使用者的點選行為沒有曝光行為頻繁,所以簡單處理,每次點選進行埋點上報。
import { track } from './sendData'
export default class Click {
add(entry) {
const tp = entry.el.attributes['track-params'].value
entry.el.addEventListener('click', function() {
track(tp)
})
}
}
- 上報函式
sendData.js
上報函式未具體實現,如果需要提供,後續私信完善。
import config from './config'
/**
* 事件上報
* @param {Object} params
*/
export function track(params) {
// 這裡自己封裝fetch或者axios,在攔截器中實現公共引數上報
console.log(`Track data to server ${config.serverUrl}: ${JSON.stringify(params)}`)
}
三、使用
- 引入全域性指令
// main.js
import './directives/track'
- 頁面使用自定義指令完成上報
// 點選事件
<div v-track:click></div>
// 點選事件帶引數
<div v-track:click :track-params="12455"></div>
// 曝光事件
<div v-track:exposure></div>
// 曝光事件帶引數
<div v-track:exposure :track-params="12455"></div>
// 曝光事件並點選帶引數
<div v-track:click|exposure :track-params="12455"></div>
以上,記錄vue專案如何進行宣告式埋點,不足之處望指正,不喜勿噴!