Vue3埋点指令封装

😎前言:对于Vue项目来说,如果遇到一个埋点的需求,我们最好的解决方案就是封装一个指令,然后再有埋点需求的地方使用,接下来就来封装一个埋点指令吧。👇👇

代码实现

track.ts文件

javascript 复制代码
import HttpAxios from '@/utils/axios'
​
//定义埋点请求
export function track(params) {
  return HttpAxios.post(
    'http://xxxxxx.xxxxx',
    params,
    {
      isCloseLoading: true
    }
  )
}
​
export default {
  install(Vue, options) {
    options = options || {}
    /**
     * 格式化绑定到dom上的数据
     * @param {*} binding
     */
    function formatBinding(binding) {
      let trackData = ''
      let eventMode = 'click'
      if (typeof binding.value === 'object') {
        if ('event' in binding.value) {
          eventMode = binding.value.event
        }
        if ('data' in binding.value) {
          trackData = binding.value.data
        } else {
          trackData = binding.value
        }
      } else {
        trackData = binding.value
      }
      return {
        eventMode,
        trackData
      }
    }
    // 初始化
    if ('init' in options && options.init instanceof Function) {
      try {
        options.init()
      } catch (error) {
        if (options.debug) {
          console.log(error)
        }
      }
    }
    Vue.directive('track', {
      mounted(el, binding) {
        const format = formatBinding(binding)
        el.trackData = format.trackData
        const params = {
          systemName: options.systemName,
          ...el.trackData //指令绑定的数据
        }
        el.addEventListener(format.eventMode, e => {
          try {
            if ('callback' in options && options.callback instanceof Function) {
              options.callback(params)
            } else {
              // 若未定义回调函数,则默认调用track方法
              track(params)
            }
            if (options.debug) {
              console.log(el.trackData)
            }
          } catch (error) {
            if (options.debug) {
              console.log(error)
            }
          }
        })
      },
      update(el, binding) {
        const format = formatBinding(binding)
        el.trackData = format.trackData
      }
    })
  }
}

main.ts文件

javascript 复制代码
// 引入埋点
import VTrack from '@monorepo/shared/utils/track'
​
// 创建vue实例
const app = createApp(App)
​
// 1.挂载埋点,没有回调函数的方式
app.use(VTrack, { systemName: '基础平台', debug: false })
​
// 2.挂载埋点,回调函数的方式
app.use(VTrack, {
  callback(data, e) {
    //可以自定义埋点请求
    console.log(data, e);
  },
  systemName: '基础平台',
  debug: false,
});

使用:

xml 复制代码
<template>
  <button v-track="{ menuName: '按钮' }">DEBUG</button>
</template>

关于指令项目规范化

src目录下,创建directives文件夹存放该项目所需的指令,如图所示:

index.ts文件统一注册指令:

typescript 复制代码
import type { App } from 'vue'
import { hasRole } from './permission/hasRole'
import { hasPermi } from './permission/hasPermi'
​
/**
 * 导出指令:v-xxx
 * @methods hasRole 用户权限,用法: v-hasRole
 * @methods hasPermi 按钮权限,用法: v-hasPermi
 */
export const setupAuth = (app: App<Element>) => {
  hasRole(app)
  hasPermi(app)
}

main.ts文件

javascript 复制代码
// 指令
import * as directives from '@/directives'
​
// 创建vue实例
const app = createApp(App)
​
// 注册指令
for (const key in directives) {
  directives[key](app)
}

大功告成🎉🎉🎉

相关推荐
水银嘻嘻22 分钟前
12 web 自动化之基于关键字+数据驱动-反射自动化框架搭建
运维·前端·自动化
it_remember23 分钟前
新建一个reactnative 0.72.0的项目
javascript·react native·react.js
小嘟嚷ovo1 小时前
h5,原生html,echarts关系网实现
前端·html·echarts
十一吖i1 小时前
Vue3项目使用ElDrawer后select方法不生效
前端
只可远观1 小时前
Flutter目录结构介绍、入口、Widget、Center组件、Text组件、MaterialApp组件、Scaffold组件
前端·flutter
周胡杰1 小时前
组件导航 (HMRouter)+flutter项目搭建-混合开发+分栏效果
前端·flutter·华为·harmonyos·鸿蒙·鸿蒙系统
敲代码的小吉米2 小时前
前端上传el-upload、原生input本地文件pdf格式(纯前端预览本地文件不走后端接口)
前端·javascript·pdf·状态模式
是千千千熠啊2 小时前
vue使用Fabric和pdfjs完成合同签章及批注
前端·vue.js
da-peng-song2 小时前
ArcGIS Desktop使用入门(二)常用工具条——数据框工具(旋转视图)
开发语言·javascript·arcgis
九月TTS2 小时前
TTS-Web-Vue系列:组件逻辑分离与模块化重构
前端·vue.js·重构