vue中教你用decorator實(shí)現(xiàn)無痕埋點(diǎn)

什么是埋點(diǎn)?

埋點(diǎn)分析,是網(wǎng)站分析的一種常用的數(shù)據(jù)采集方法。數(shù)據(jù)埋點(diǎn)分為初級、中級、高級三種方式。數(shù)據(jù)埋點(diǎn)是一種良好的私有化部署數(shù)據(jù)采集方式。

埋點(diǎn)技術(shù)如何采集數(shù)據(jù),有何優(yōu)缺點(diǎn)?
數(shù)據(jù)埋點(diǎn)分為初級、中級、高級三種方式,分別為:

  • 初級:在產(chǎn)品、服務(wù)轉(zhuǎn)化關(guān)鍵點(diǎn)植入統(tǒng)計(jì)代碼,據(jù)其獨(dú)立ID確保數(shù)據(jù)采集不重復(fù)(如購買按鈕點(diǎn)擊率);
  • 中級:植入多段代碼,追蹤用戶在平臺每個界面上的系列行為,事件之間相互獨(dú)立(如打開商品詳情頁——選擇商品型號——加入購物車——下訂單——購買完成);
  • 高級:聯(lián)合公司工程、ETL采集分析用戶全量行為,建立用戶畫像,還原用戶行為模型,作為產(chǎn)品分析、優(yōu)化的基礎(chǔ)。

無疑,數(shù)據(jù)埋點(diǎn)是一種良好的私有化部署數(shù)據(jù)采集方式。數(shù)據(jù)采集準(zhǔn)確,滿足了企業(yè)去粗取精,實(shí)現(xiàn)產(chǎn)品、服務(wù)快速優(yōu)化迭代的需求。

但,因手動埋點(diǎn)工程量極大,且一不小心容易出錯,成為很多工程師的痛。且其開發(fā)周期長,耗時費(fèi)力。無痕埋點(diǎn)成為市場新寵。

什么是無痕埋點(diǎn)

首先介紹一下傳統(tǒng)埋點(diǎn)存在的問題

  • 數(shù)據(jù)質(zhì)量(埋錯、漏埋)
  • 開發(fā)成本 (需要統(tǒng)計(jì)每個事件的點(diǎn)擊,頁面的展現(xiàn)pv uv)
無痕埋點(diǎn)就是為了解決這兩個問題,一行代碼完成統(tǒng)計(jì),無遺漏。
下面先介紹一下本公司vue實(shí)現(xiàn)埋點(diǎn)插件
   function leStatic(actiontype, pagetype='',backup = {}){
      ...
      ...
   };

   Vue.prototype.$log = leStatic;

將埋點(diǎn)方法注冊到vue實(shí)例下;我們就可以使用 this.$log()來調(diào)用這個方法了,每調(diào)用一次這個方法就會埋上一個埋點(diǎn);

鋪墊完成,接下來該開始我們的表演了

1、我們的無痕埋點(diǎn)能做什么?

* 統(tǒng)計(jì)所有頁面內(nèi)事件的點(diǎn)擊量
* 統(tǒng)計(jì)頁面的展現(xiàn)量pv uv

2、怎么應(yīng)用?

應(yīng)用很簡單,只需要引入封裝的方法(Buried),并應(yīng)用在methods即可

import { Buried } from '@/libs/decorators';

@Buried
methods: {
   ...
}

3、需要注意什么?

  • 此方法不局限在methods上是使用,只要是在單文件導(dǎo)出對象一級子對象下均可;
  @Buried
  components: {}

但是考慮到語義更加清晰建議在methods上使用此方法。

  • 考慮到并不是所有的方法都需要設(shè)置埋點(diǎn),所以如果某方法不想設(shè)置埋點(diǎn) 可以 return 'noBuried' 即可忽略此方法不設(shè)埋點(diǎn)。

  • 頁面展現(xiàn)量統(tǒng)計(jì)在鉤子函數(shù)中 (activated - created - mounted) 這三個鉤子內(nèi),所以頁面內(nèi)至少有這個三個鉤子之一才可統(tǒng)計(jì)頁面展現(xiàn)量。

4、話不多說,先上代碼?

/**
 * @description 全埋點(diǎn) 
 *  1.在所有methods方法中埋點(diǎn)為函數(shù)名
 *  2.在鉤子函數(shù)中 (activated - created - mounted) 依次尋找這三個鉤子
 *    如果存在就會增加埋點(diǎn) VIEW
 * 
 * 用法: 
 *   @Buried
 *   在單文件導(dǎo)出對象一級子對象下;
 *   如果某方法不想設(shè)置埋點(diǎn) 可以 return 'noBuried' 即可
 */
export function Buried(target, funcName, descriptor) {
  let oriMethods = Object.assign({},target.methods),
      oriTarget = Object.assign({},target);
  // methods方法中
  if(target.methods) {
    for(let name in target.methods) {
      target.methods[name] = function () {
        let result = oriMethods[name].call(this,...arguments);
        // 如果方法中返回 noBuried 則不添加埋點(diǎn)
        if(typeof result === 'string' && result.includes('noBuried')) {
          console.log(name + '方法設(shè)置不添加埋點(diǎn)');
        } else if(result instanceof Promise) {
          result.then(res => {
            if(typeof res === 'string' && res.includes('noBuried')) { console.log(name + '方法設(shè)置不添加埋點(diǎn)'); return; };
            console.log('添加埋點(diǎn)在methods方法中:' , name.toUpperCase ());
            this.$log(name);
          });
        }else{
          console.log('添加埋點(diǎn)在methods方法中:' , name.toUpperCase ());
          this.$log(name);
        };
        return result;
      }
    }
  }
  // 鉤子函數(shù)中
  const hookFun = (funName) => {
    target[funName] = function() {
      let result =  oriTarget[funName].call(this,...arguments);
      console.log('添加埋點(diǎn),在鉤子函數(shù)' + funName + '中:', 'VIEW');
      this.$log('VIEW');
      return result;
    }
  }
  // 鉤子函數(shù)中 view
  if (target.activated) {
    return hookFun('activated');
  } else if (target.created) {
    return hookFun('created');
  } else if (target.mounted) {
    return hookFun('mounted');
  };
}

簡單的實(shí)現(xiàn)了無痕埋點(diǎn)的實(shí)現(xiàn)方案,目前在項(xiàng)目中運(yùn)轉(zhuǎn)正常。大大減少了開發(fā)者的工作量,預(yù)防了賣錯、漏埋導(dǎo)致上線后無數(shù)據(jù)統(tǒng)計(jì)情況發(fā)生。如果有更好的建議,請聯(lián)系我哦~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容