VUE 曝光埋点插件的实现原理

vue自定义 插件

说到vue插件,vue就提供了自定义插件的功能。

定义

定义一个文件,这个文件 导出一个对象,这个对象包含install方法。
install方法有两个参数 一个是vue构造器 一个是使用插件时传入的参数。

const log = require("./core");// 具体 log方法
const logPlugin = {install(vue, options) {if (vue.$prototype.isServer) return;// 一些自己想做的事情// 全局添加方法属性,添加自定指令,注入mixin}}module.exports = logPlugin; // 单独使用的插件一般使用commonjs规范,向外暴露,并且适配性高

使用

import { VueLog } from "log";
Vue.use(VueLog, { eventType: 'click', actionType: 'page-icon', pageType: 'info-page' })
// 第一个参数就是你导出的自定义插件 第二个参数就是对应插件中install中第2个参数options 你可以传入一些属性

vue 自定义指令

因为我们需要做的是曝光dom,所以我们需要一个自定指令安装到dom上,来收集dom信息,并且确定这个dom是需要曝光埋点的

定义

参数
vue-directive有两个参数,第一个是指令名称,无需带v,如log-exp,第2个参数是一个对象,这个对象包含四个钩子函数,均为可选

  • bind
    bind只执行一次 ,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
  • inserted
    被绑定元素插入到父节点时调用,仅保证父元素存在,不保证绑定元素已经插入到文档中。
  • update
    被绑定元素的vnode发生改变时调用,可能发生在其子vnode更新之前,指令值可能变化了,也可能没变化
  • componentUpdated
    被绑定元素vnode及其子vnode全部更新后调用

钩子函数参数
每个钩子函数都有两个参数,第一个是el即被绑定元素实例,可以用来直接操作dom,第二个元素binding是一个对象,包含以下几个属性:

  • name
    指令名 不包含v-
  • value
    指令的绑定值,如v-log-exp=”1+1“,此值为2
  • oldValue
    指令绑定的前一个值,仅在update和comoponentUpdated中可用
  • expression
    字符串形式的指令表达式,如v-log-exp=”1+1“,此值为1+1
  • arg
    传给指令的参数,如v-log-exp:a=‘1’ ,此值为a
  • modifiers
    指令的修饰符对象,如v-log-exp.foo.bar,此值为{foo:true,bar:true}
  • vnode
    指令绑定的虚拟dom
  • oldVnode
    指令绑定的更新前的虚拟dom节点,仅在update和comoponentUpdated中可用

注意事项

  • 参数中除了el外,其他只是可读的,不要去操作它
  • 自定义指令的第二个也可以是一个方法,不写钩子函数的话,vue默认方法会执行在bind 和update中

具体实践

const logPlugin = {install(vue, options) {if (vue.$prototype.isServer) return;vue.directive('log-exp', { // 进行一个指令的定义bind: (el, bindings) => {const args = JSON.stringify(bindings.value);el.setAttribute('data-log-exp', args); // 将绑定的值声明为实例上的属性,便于后续曝光的时候获取}})}}

使用

<div v-log-exp="{a:1}"></div> // 绑定自己声明的对象

曝光对象intersection-observer

定义

intersection-observer提供了一个异步观察目标元素与其祖先元素或顶级文档元素(viewport)交叉状态变化的方法。不随着目标元素的滚动同步触发。这是它相比监听滚动的优势。
祖先元素与视窗(viewport)被称为根(root)。

** 参数**
new IntersetctionObserver(callback,{})有两个参数,第一个参数是回调函数,
回调函数总共有两个值:

  • entries:
    目标观察对象数组
  • observer
    被调用的IntersetctionObserver对象实例

第二个参数是一个对象,主要有三个值:

  • root
    详细设置观察元素的祖先元素,设置后会观察目标元素与此祖先元素交叉状态的变化,默认null,指向顶级根元素
  • rootMargin
    计算交叉时添加到root元素的矩形偏移量,可以有效夸大或缩小根的范围来满足需求。可以用px或% 默认是0px;
    类似于向root元素添加了一个margin,当目标元素与margin相交时就会触发变化;相当于扩大了或缩小margin的范围,可以提前进行下一步操作。
  • thresholds
    一个阈值列表,升序排列。代表监听对象交叉区域和边界区域的比例。当监听对象的任何阈值被越过时,会生成一个通知,触发回调函数
    在我看来,代表监听元素出现在视图中的,一般出现一半就代表已经曝光了
    api
  • observer
    监听一个对象
  • unobsever
    停止监听一个对象

使用

在我们的自定义插件中使用Exposure对象,并在bind时像此对象添加el作为观察对象

const Exposure = require("./core/exposure")
const logPlugin = {install(vue, options) {if (vue.$prototype.isServer) return;const observe = new Exposure(options);// 初始化对象,绑定回调及其他vue.directive('log-exp', { // 进行一个指令的定义bind: (el, bindings) => {const args = JSON.stringify(bindings.value);el.setAttribute('data-log-exp', args); // 将绑定的值声明为实例上的属性,便于后续曝光的时候获取observe.add(el);// 观察此dom}})}}module.exports = logPlugin; // 单独使用的插件一般使用commonjs规范,向外暴露,并且适配性高

Exposure对象对IntersetctionObserver包装了一下,声明了一些使用的变量和函数

if (window) {require('intersection-observer'); // 引入observerIntersectionObserve.prototype['THROTTLE_TIMEOUT'] = 200;// 原型上的防抖策略时间根据需求更改一下
}module.exports = class Exposure {constructor(options) {// 使用使用的对象this.argData = [] // 要上报的数据this.maxNum = options.maxNum || 10; // 达到最大阈值,立马调用上报this.options = options;this._observer = null; // IntersectionObserver对象this._timer = null; //定时器 隔一段时间上报一次,提高效率this.init()}init() {const that = this;this._observer = new IntersectionObserver(// 回调函数function (entries, observer) {entries.forEach((entry) => {if (entry.isIntersecting) { // 代表触发了,出现在视图中了clearTimeout(that._timer);// 连续触发就清楚定时器,类似节流const arg = entry.target.attributes['data-log-exp'];// 获得我们bind时绑定的数据that.argData.push(arg); // 添加到上报数据集中that._observer.unobserve(entry.target);// 取消观察 曝光只曝光一次if (that.argData.length >= that.maxNum) {// 达到阈值直接上报that.logData();// 上报}else if (that.argData.length > 0) { // 一直触发就会一直清除定时器,直至到达阈值或不在触发,到达时间会执行定时器中方法that._timer = setTimeout(() => {that.logData();// 上报}, 200)}}})}, {root: null, // 根元素rootMargin: 0, // 距离threshold: 0.5 // 超过比例})}add(entry) {this._observer.observe(entry);// 添加观察对象}logData() {const logArgs = this.argData;this.argData = [];// 置空logArgs.forEach((arg) => {log(arg, this.options) // 自己的上报方法console.log(arg);})}
}

Vue 曝光埋点插件的实现原理相关推荐

  1. 【Android 插件化】“ 插桩式 “ 插件化框架 ( 原理与实现思路 )

    Android 插件化系列文章目录 [Android 插件化]插件化简介 ( 组件化与插件化 ) [Android 插件化]插件化原理 ( JVM 内存数据 | 类加载流程 ) [Android 插件 ...

  2. Vue中使用can-autoplay插件实现浏览器不支持自动播放音频时提示点击

    场景 Vue中使用speak-tts插件实现点击按钮后进行语音播报(TTS/文字转语音): Vue中使用speak-tts插件实现点击按钮后进行语音播报(TTS/文字转语音)_BADAO_LIUMAN ...

  3. pc 图片预览放大 端vue_安利一款简单好用的Vue图片预览插件

    在项目中因为要经常用到图片预览效果,自己写的话麻烦死啦(懒) vue-photo-preview 一个基于 photoswipe 的 vue 图片预览插件,支持移动端和PC端,支持各种手势操作,放大缩 ...

  4. datax底层原理_Datax 插件加载原理

    Datax 插件加载原理 插件类型 Datax有好几种类型的插件,每个插件都有不同的作用. reader, 读插件.Reader就是属于这种类型的 writer, 写插件.Writer就是属于这种类型 ...

  5. .net core image怎么保存_轻量级Vue图片上传插件——Vue-core-image-Upload

    介绍 vue-core-image-upload 是一款轻量级的 Vue.js 上传插件,它可以支持的图片的上传,裁剪,压缩.它同样也支持在移动端的图片处理,它定义了诸多上传周期,你可以自由的进行流程 ...

  6. Vue调试神器vue-devtools - 插件下载安装

    文章目录 Google如何安装调试Vue的神器`vue-devtools` ? 安装介绍: demo实例 - 演示代码: 相关文章链接: 1. https://github.com/vuejs/vue ...

  7. 写一个简单易用可扩展vue表单验证插件(vue-validate-easy)

    写一个vue表单验证插件(vue-validate-easy) 需求 目标:简单易用可扩展 如何简单 开发者要做的 写了一个表单,指定一个name,指定其验证规则. 调用提交表单方法,可以获取验证成功 ...

  8. siwper vue 上下滑动分页_支持移动端的vue滑动轮播图插件vueswiper

    一款支持移动端的vue滑动轮播图插件vueswiper,演示页面给出了5中范例:基本例子.垂直滚动.不定宽度.无缝循环滚动.多层级滚动,每一种都可以通过鼠标拖动图片来滑动,可以点击按钮来增加页面查看效 ...

  9. Vue中引入swiper插件报错:To install it, you can run: npm install --save swiper/css/swiper.css

    Vue中引入swiper插件报错:To install it, you can run: npm install --save swiper/css/swiper.css 今天在写项目的时候用到了Sw ...

最新文章

  1. CCF201312-5 I’m stuck!(100分)
  2. 1500+ FPS!目前最快的CNN人脸检测算法开源
  3. 今天看到“黑涩会MM”了
  4. .netCHARTING图表控件详细介绍及下载
  5. 网关 配置内网DNS 服务器
  6. 将给定的字符串划分为所有可能的IP地址 Restore IP Addresses
  7. 正视苦难,民族的心灵史——1942
  8. [BUG记录]java.lang.IllegalArgumentException: The observer is null.异常解决方案
  9. 华为认证hcia含金量_华为hcna认证含金量高吗 华为hcna认证用处大吗
  10. 使用 vue 开发一个简单的滑块拖动验证码
  11. 人大金仓数据库使用uuid
  12. 【知识分享】Batch(批处理)-学生管理系统可视化界面的应用
  13. Java IO流的分类
  14. 汽车电线束双绞线技术参数设定
  15. 电池SOC仿真系列-基于EKF算法的电池SOC估算研究
  16. 中职计算机教师试讲技巧,中职教师资格面试原来是这样考的的!
  17. PTA翁恺7-6 厘米换算英尺英寸 (15 分)
  18. 玩客云刷linuxARMBIAN当服务器过程记录
  19. mysql stop failed_Mysql报错:Failed to stop mysqld.service: Unit mysqld.service not loaded.
  20. MFCC和fbank的区别

热门文章

  1. 大疆前端开发笔试总结
  2. Hadoop学习笔记-基本操作、历史服务器和log汇总
  3. 习题 14.1 求一元二次方程式ax^2+bx+c=0的实根,如果方程没有实根,则输出有关警告信息。
  4. NET程序员讨论技术群
  5. Nicholas C. Zakas:我热爱互联网技术的种种异端
  6. 电网:数据库-数据模型与数据系统结构
  7. MsgPack的浅浅理解
  8. 非物质文化遗产的法律保护模式(九)
  9. 从中粮到克明,五谷道场还有逆袭机会吗?
  10. C#通过OPC协议连接PLC