1. 程式人生 > 實用技巧 >vue專案埋點之指令埋點(點選和曝光)

vue專案埋點之指令埋點(點選和曝光)

埋點方案有命令式埋點和宣告式埋點。

  • 命令式埋點:在使用者行為觸發位置呼叫事件上報函式進行行為上報,缺點是埋點和業務耦合度比較高,工作量比較大
  • 宣告式埋點:通過自定義指令統一完成事件上報,使得埋點和業務程式碼一定程度上解耦合。
    本篇文章將記錄藉助vue自定義指令完成宣告式埋點,降低前端埋點壓力。

一、準備工作

這裡關於vue自定義指令和IntersectionObserver不做詳細介紹,自行前往官網瞭解學習。

二、程式碼實現

  • 建立指令
    這裡我們計劃建立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專案如何進行宣告式埋點,不足之處望指正,不喜勿噴!