vue 数据上报组件

1,504 阅读1分钟

有些场景下,需要我们去上报一些数据,给到BI进行统计。 为了简化上报步骤,使用自定义指令进行数据上报封装。

如何使用?

// 引入
import Vue from 'vue'
import { Report } from './components/testReport'
Vue.use(Report)
// dom use
<p v-report.view="reportObj">沙发上纷纷</p>
<p v-report.click="reportObj">沙发上111</p>
<p v-report="reportObj">沙发上111</p>

testReport 内容


import RePortEventInfo from './event-info'
let Report = {}
Report.RePortEventInfo = RePortEventInfo
Report.install = function (Vue) {
  Vue.directive('report', {
    inserted: function (el, binding) {
      // view 上报
      console.log(binding)
      if (binding.modifiers.view || (!binding.modifiers.view && !binding.modifiers.click)) {
        Report.RePortEventInfo(binding.value)
      }
      // 点击上报
      if (binding.modifiers.click) {
        el.addEventListener('click', function () {
          Report.RePortEventInfo(binding.value)
        })
      }
    }
  })
}

export {
  Report
}

上报到BI函数封装,进行统一,具体上报的字段、id双方沟通好。 eg:

reportObj = {
  event_id: '', // 必传 具体申请操作在https://appdata.oa.fenqile.com
  label: '', // 选传 在申请event_id时创建
  tag_list: [], // 选传 渠道码过滤标签key数组
  extend_info: {} // 选传拓展字段对象集合
}

event-info.js 内容

import axios from 'axios'
export default function (evt = {}) {
  reportEventInfoH5(evt)
}
function reportEventInfoH5 (evt) {
  axios.post('/XXXXXXXX/uploadData.json', {
    data: {
      system: {
        app_version: '',
        new_version: '',
        machine_code: '',
        os: 'H5'
      },
      data_list: [{
        data_type: 2,
        record_list: [{
          event_id: evt.event_id,
          label: evt.label || '',
          time: Date.now(),
          extend_info: evt.extend_info
        }]
      }]
    }
  })
}

数据动态曝光

利用IntersectionObserver 进行实现, 详看:参考链接


obDOMExposure_list = (function() {
  let intersectionObserver = null
  return function(el, cb) {
    if (!intersectionObserver) {
      if (typeof IntersectionObserver !== 'undefined') {
        intersectionObserver = new IntersectionObserver(
          entries => {
            entries.forEach(entry => {
              // 完全出现在视野调用
              if (entry.intersectionRatio === 1) {
                const target = entry.target
                cb(target)
                //只曝光一次
                intersectionObserver.unobserve(target)
              }
            })
          },
          {
            root: null,
            threshold: [1.0]
          }
        )
      }
    }
    let nodes = document.querySelectorAll(el)
    nodes.forEach(node => {
      intersectionObserver.observe(node)
    })
  }
})()

export let obDOMExposure_list = obDOMExposure_list

其他相关dom API

/**
 * 获取当前dom上最大的z-index 自加1
 */
export function getZIndex() {
  let index = [...document.all].reduce((r, e) => Math.max(r, +window.getComputedStyle(e).zIndex || 0), 0)
  return ++index
}

// 平滑滚动 by 张鑫旭
export function scrollSmoothTo(position) {
  if (!window.requestAnimationFrame) {
    window.requestAnimationFrame = function(callback, element) {
      return setTimeout(callback, 17)
    }
  }
  // 当前滚动高度
  var scrollTop = document.documentElement.scrollTop || document.body.scrollTop
  // 滚动step方法
  var step = function() {
    // 距离目标滚动距离
    var distance = position - scrollTop
    // 目标滚动位置
    scrollTop = scrollTop + distance / 5
    if (Math.abs(distance) < 1) {
      window.scrollTo(0, position)
    } else {
      window.scrollTo(0, scrollTop)
      requestAnimationFrame(step)
    }
  }
  step()
}