<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          vue聲明式埋點指令

          共 7134字,需瀏覽 15分鐘

           ·

          2021-09-01 07:00

          背景

          數(shù)據(jù)埋點是前端開發(fā)中的必經(jīng)一環(huán),可以用于統(tǒng)計頁面訪問量、按鈕點擊量、元素展示次數(shù)等。常見的是每個公司都會封裝一套自己的埋點sdk,在JS邏輯中調(diào)用對應(yīng)函數(shù)上報數(shù)據(jù)埋點。這種埋點的優(yōu)點是可以在元素多狀態(tài)的時候進行區(qū)分上報,缺點就是與業(yè)務(wù)邏輯耦合。

          本文借助vue指令的實現(xiàn)了一套聲明式埋點方案,可以直接在template上進行指令埋點上報。為了適用不同公司,并且不對現(xiàn)有業(yè)務(wù)進行大的改動,將具體的埋點上報函數(shù)交由業(yè)務(wù)方實現(xiàn),將上報函數(shù)作為參數(shù)初始化指令。

          實現(xiàn)

          核心原理就是利用vue指令,指令的開發(fā)就不再描述了,需要的同學(xué)可以去vue官網(wǎng)看文檔。

          常見的埋點可以分為三類:

          1. 頁面PV

            一般是頁面初始化時進行上報,在指令初始化的時候上報即可,比較容易實現(xiàn)

          2. 點擊click

            Vue 指令初始化時,會傳遞綁定指令的dom元素,所以我們可以通過對dom添加點擊事件進行監(jiān)聽來實現(xiàn)

          3. 元素曝光show

            元素曝光實現(xiàn)稍微復(fù)雜些,需要借助IntersectionObserver來判斷元素是否進入可視區(qū)域。

          import "intersection-observer";
          import { ITrackOptions } from "./types";

          let ksLogShow: (arg0: any) => void;

          const observer = new IntersectionObserver(
              (entries) => {
                  entries.forEach(function (entry{
                      if (entry.isIntersecting) {
                          let value: any = entry.target.getAttribute("kstrackParams");
                          const once = entry.target.getAttribute("once");
                          if (!value) {
                              return;
                          }
                          value = JSON.parse(value);
                          ksLogShow(value);
                          if (once === "true") {
                              observer.unobserve(entry.target);
                          }
                      }
                  });
              },
              {
                  threshold: [0.5],
              }
          );

          export default {
              install(Vue: any, options: ITrackOptions) {
                  const { logClick, logPV, logShow } = options;
                  ksLogShow = logShow;
                  Vue.directive("track", {
                      bind(el: any, binding: any) {
                          const { arg, value, modifiers } = binding;
                          if (arg === "click") {
                              el.addEventListener("click", () => {
                                  logClick(value);
                              });
                          } else if (arg === "show") {
                              if (modifiers.once) {
                                  el.setAttribute("once", modifiers.once.toString());
                              }
                              el.setAttribute("kstrackParams"JSON.stringify(value));
                              observer.observe(el);
                          } else if (arg === "pv") {
                              logPV(value);
                          }
                      },
                  });
              },
          };

          使用方式

          指令使用的參數(shù),與業(yè)務(wù)自己定義的logPV、logClick、logShow三個函數(shù)的參數(shù)是對應(yīng)的,參數(shù)的定義、實現(xiàn)、使用,全部由業(yè)務(wù)方自己決定。

          初始化

          import Vue from 'vue';
          import logger from 'vue-logger-directive'
          // 需要業(yè)務(wù)方提供三個函數(shù),分別用于PV統(tǒng)計、點擊統(tǒng)計、展示統(tǒng)計
          import { logPV, logClick, logShow } from './logHandler';
          Vue.use(logger, { logPV, logClick, logShow });

          PV統(tǒng)計

          export function logPV(params: {
              page: string;
              type: number;
          }
          {}

          <div class="app"
              v-logger:pv="{page: "app", type: 1}">
          </div>

          點擊統(tǒng)計

          export async function logClick(params: {
              page: string;
              type: number;
              action: string;
          }
          {
              // 點擊統(tǒng)計邏輯
          }

          // 組件使用時
          <div class="card" v-logger:click="{page: 'app', type: 1, action: 'join-btn'}"></div>

          元素曝光

          export async function logShow(params: {
              page: string;
              type: number;
              action: string;
          }
          {
              // 展示統(tǒng)計邏輯
          }

          // 組件使用時
          <div class="card" v-logger:show="{page: 'app', type: 1, action: 'main-card'}"></div>

          /
          / 支持元素展示只執(zhí)行一次
          <div class="card" v-logger:show.once="{page: 'app', type: 1, action: 'main-card'}"></
          div>

          最后為了方便后續(xù)使用,發(fā)布到了npm中,有需要的可以自取

          npm包地址:https://www.npmjs.com/package/vue-logger-directive


          推薦閱讀
          1. Esbuild 為什么那么快

          2. Vite 的好與壞

          3. Vue.js 組件復(fù)用和擴展之道

          4. Vue.js 記錄片

          5. Vue 動態(tài)組件按需加載

          6. vue.Observable使數(shù)據(jù)具有響應(yīng)特性,基于它我們可以實現(xiàn)自己的微型vuex

          瀏覽 126
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  在线天堂a 8 | 婷婷导航中文 | 国产成人视频在线播放 | 亚洲男女免费啪啪视频 | 国产原创AV在线播放 |