Vue中使用matomo进行访问流量统计的实现


Posted in Javascript onNovember 05, 2019

前言

之前做到了一个页面及接口访问流量统计的需求, 然后在网上找了很多帖子,发现有些有的但是写的都不是很详细,所以今天就整理了一下

正文

第一步

首先自然是引入matomo

npm i vue-matomo

第二步

在main.js中注册一下matomo

import VueMatomo from 'vue-matomo'
Vue.use(VueMatomo, {
 host: 'http://matomo.na.xyz', // 这里配置你自己的piwik服务器地址和网站ID
 siteId: 3,//siteId值
 // 根据router自动注册
 router: router,
 // // 是否需要在发送追踪信息之前请求许可
 // // 默认false
 requireConsent: false,
 enableLinkTracking: true,
 // // 是否追踪初始页面
 // // 默认true
 trackInitialView: false,
 // // 最终的追踪js文件名
 // // 默认 'piwik'
 trackerFileName: 'matomo',
 debug: false
});

当然这里也可以提出一个公共的文件来动态维护你的piwik服务器地址和网站

import VueMatomo from 'vue-matomo'
// 动态维护的文件
import baseUrlto from './utils/baseUrlto'

// 这段代码作用是获取当前加载的路径,并去维护文件中数组里匹配出相应的的集合对象.
let uitem
baseUrlto.map(e => {
 if (document.URL.indexOf(e.environmentUrl) !== -1) {
 uitem = e
 }
})
if (!uitem) {
 uitem = baseUrlto[0]
}
Vue.use(VueMatomo, {
 host: uitem.staUrl, // 这里是匹配到的地址
 siteId: uitem.staId, //这里是匹配到的siteId值
 // 根据router自动注册
 router: router,
 // // 是否需要在发送追踪信息之前请求许可
 // // 默认false
 requireConsent: false,
 enableLinkTracking: true,
 // // 是否追踪初始页面
 // // 默认true
 trackInitialView: false,
 // // 最终的追踪js文件名
 // // 默认 'piwik'
 trackerFileName: 'matomo',
 debug: false
});

附上baseUrlto的代码

const statistics = [
// 数组第一项,即为,当路径匹配不到时,默认传送的统计网址,可以是开发环境下测试统计的地址
 {
 staUrl: '//analytics.baowei-inc.com/', // 统计网址
 staId: '2', // 统计ID
 environmentUrl: '默认'
 },
 {
 staUrl: '//analytics.baowei-inc.com/', // 开发环境统计网址
 staId: '2', // 统计ID
 environmentUrl: 'http://bwcaigou.baowei-inc.com'
 },
 {
 staUrl: '//analytics.baowei-inc.com/', // 生产环境统计网址
 staId: '1', // 统计ID
 environmentUrl: 'http://portal.baowei-inc.com'
 },
 {
 staUrl: '//106.12.95.245:8888/', // 本地环境统计网址
 staId: '2', // 统计ID
 environmentUrl: 'http://localhost:'
 }
]

export default statistics

第三步 ,是在app.vue中监听路由变化

watch: {
  '$route' () {
  let locationHash = window.location.hash;
  //把路由存在缓存中,此处你可以console.log看出路由变化
  sessionStorage.setItem("hashLocation",locationHash);
  }
 },

第四步, 然后在每一个被跳转时都需要统计的组件中,添加上一段追踪信息的代码,每一个页面组件, 对于反复使用的子组件不需要添加,弹窗等也不需要,针对的是页面级得组件,

// 这里说明一下, this.$matomo是注册过后,自动会有得, 不需要进行其他得操作.
 created(){
  const hashLocation= sessionStorage.getItem("hashLocation");//缓存中获取当前页面的路由名称
  const newLocation = hashLocation.split("#/")[1];
  // 注意, 这里使用全路径匹配,在hash模式中,因为地址会携带#,所以页面报告中的url需要重新覆盖一下, 将#去除
  this.$matomo.setCustomUrl("http:baidu.com"+"/"+newLocation);//覆盖页面报告的url,可以自定义页面url,加上本页面路由
  // this.$matomo.trackEvent(shopCode,hashLocation);//事件
  this.$matomo.trackPageView(hashLocation);//页面名称,可以自定义页面名称
 }

图片现在上传不了,稍后回去上传上来,

特地说明一下, setCustomUrl的作用是重新设定url,因为在matomo的页面网址统计那块中,它是通过url去统计的, 如果不做处理的话, 会自动统计域名后一级目录为相同页面, 也就是说, /#/会被读取为一个页面网址,不处理的话,那么无论访问哪个页面,都会被统计为/index页面.

// 注意, 这里使用全路径匹配,在hash模式中,因为地址会携带#,所以页面报告中的url需要重新覆盖一下, 将#去除
  this.$matomo.setCustomUrl("http:baidu.com"+"/"+newLocation);// 非全路径
  this.$matomo.setCustomUrl("http://www.baidu.com"+"/"+newLocation); // 全路径
  //覆盖页面报告的url,可以自定义页面url,加上本页面路由

重要的事说两遍, 需要全路径字符串, 否则依然会把#带上.

第五步, 其实到这里, 已经能正常统计数据了,下面是一些优化的步骤.

针对接口的统计

针对接口的统计就是在请求拦截器中添加发送统计信息的代码

import pathToname from '@/utils/pathname'
// 请求拦截器
service.interceptors.request.use(
config => {
 if (config.url.indexOf('/login') === -1) {
 // 设置用户名
 const name = store.getters.name
 let urlName
 let curl = config.url
 curl = curl.split('?')[0] || curl
 // 将请求地址转为中文
 for (const k in pathToname) {
  if (curl === k) {
  urlName = pathToname[k]
  } else {
  const kurl = k
  const turl = curl
  const karr = kurl.split('/')
  if (karr[karr.length - 1] === '*') {
   // 代表最后一位为*
   karr.splice(karr.length - 1, 1)
   const karr1 = turl.split('/')
   karr1.splice(karr1.length - 1, 1)
   const str = karr.join('/')
   const str2 = karr1.join('/')
   if (str === str2) {
   urlName = pathToname[k]
   }
  } else {
   karr.splice(karr.length - 2, 1)
   const str = karr.join('/')
   const karr1 = turl.split('/')
   karr1.splice(karr1.length - 2, 1)
   const str2 = karr1.join('/')
   if (str === str2) {
   urlName = pathToname[k]
   }
  }
  }
 }
 // urlName = urlName || '其他'
 urlName = urlName || config.url
 window._paq.push(['setCustomUrl', `${document.URL.split('/#')[0]}${curl}123`])
 window._paq.push(['setDocumentTitle', urlName])
 window._paq.push(['setUserId', name])
 window._paq.push(['trackPageView'])
 }

图片依然等回去上传

当然,我这里用的是js的方式原理是一样的,上面的代码,是我对统计的地址名做了中文化的匹配.因为接口的多样性,需要做一个处理,比如说,路径传参中, 其实只是参数变了,地址没变, 这个时候不能算一个新的地址, 所以就需要匹配处理. 代码没写太复杂, 一步一步深入,基本上很容易懂.

附上pathname的代码. 用于将地址匹配为中文统计,:

const changeName = {
// goods相关API
'/pdc/api/v1/dic/query': '基础档案管理-获取货品信息',
'/pdc/api/v1/product/query': '基础档案管理-获取货品详情',
// role相关API
'/api/root/list': '基础-获取菜单权限',
'/api/createRole': '权限管理-创建角色',
'/api/checkRoleName': '权限管理-查询角色是否存在',
'/api/custom/master/permission': '权限管理-获取外部客户角色列表',
'/api/internal/user/info': '基础-获取用户信息',
// statement相关API
'/statement/financialForm': '财务管理-获取JIT财务列表',
'/statement/export': '财务管理-导出JIT财务报表',
'/statement/count': '财务管理-获取JIT数据总条目',
// trade相关API(待定)
// user相关API
'/api/internal/user/list': '权限管理-获取外部用户列表',
'/api/internal/custom/list': '权限管理-获取外部客户列表',
'/user/create': '权限管理-创建用户',
'/user/update': '权限管理-修改用户信息',
'/api/user/password': '权限管理-修改用户密码',
// 订单列表相关API
'/order/api/v1/orderConfirmation': 'B2B交易管理-提交订单',
'/order/api/v1/serviceApprove': 'B2B交易管理-确认订单',
'/order/api/v1/serviceRefuse': 'B2B交易管理-拒绝订单',
'/order/api/v1/getDispatchSelectInfo': 'B2B交易管理-获取订单字典数据',
'/order/api/v1/import/productList': 'B2B交易管理-导入订单数据',
'/order/api/v1/*/orderInformation': 'B2B交易管理-获取订单基本信息',
'/order/api/v1/*/customerCode': 'B2B交易管理-检查客户代码是否存在',
'/order/api/v1/*/discount': 'B2B交易管理-导入订单折扣',
'/order/api/v1/*/occupyInventory': 'B2B交易管理-导出占库结果',
'/order/api/v1/createDispatch': 'B2B交易管理-提交发货单',
'/order/api/vi/dispatchCancel': 'B2B交易管理-取消发货单',
'/order/api/vi/*/orderCancel': 'B2B交易管理-取消订单',
'/order/api/v1/dispatchApprove': 'B2B交易管理-同意发货单',
'/order/api/v1/dispatchRefuse': 'B2B交易管理-拒绝发货单',
'/order//api/v1/confirmSubmissionApproval': 'B2B交易管理-订单提交审批',
'/order/api/v1/orderStatus': 'B2B交易管理-获取订单状态',
'/bff/api/v1/dispatch/*': 'ODS管理-获取发货单基本信息',
'/bff/api/v1/receive/*': 'ODS管理-获取收货单基本信息',
'/bff/api/v1/vend-cust': 'ODS管理-获取客商列表信息',
'/bff/api/v1/warehouses': 'ODS管理-实时获取仓库信息',
'/bff/api/v1/dict/type': 'ODS管理-仓库类型查询',
'/bff/api/v1/dispatch/_export': 'ODS管理-导出发货单信息',
'/bff/api/v1/receive/_export': 'ODS管理-导出收货单信息',
'/bff/api/v1/dict/type/_list': 'ODS管理-查询字典数据',
'/bff/api/v1/dispatch/_page': 'ODS管理-查询发货单列表',
'/order/api/v1/orderList': 'B2B交易管理-查询订单列表',
'/order/api/v1/orderDetail': 'B2B交易管理-获取订单商品列表',
'/order/api/v1/orderDispatchInfo': 'B2B交易管理-获取订单发货单信息',
'/order/api/v1/dispatchList': 'B2B交易管理-获取订单发货单列表',
'/order/api/v1/confirm': 'B2B交易管理-修改占库结果',
'/order/api/v1/toBeConfirmedDispatch': 'B2B交易管理-查看历史发货单信息',
'/order/api/v1/cumulativeState': 'B2B交易管理-获取占库结果信息'
}
export default changeName

其他的就不赘述了,中文转化方面, 各人有各人的理解, 能达到效果就行.

js方式的统计也是类似的.有需要的话,评论留言,我后续传上来.

结语

Vue-matomo流量统计这块,就算整理完成了, 实际项目中已经正常使用,所以正常来讲应该不会出现问题. 加油, 各位

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
jQuery formValidator表单验证插件开源了 含API帮助、源码、示例
Aug 14 Javascript
优化 JavaScript 代码的方法小结
Jul 16 Javascript
《JavaScript高级程序设计》阅读笔记(一) ECMAScript基础
Feb 27 Javascript
Jquery中CSS选择器用法分析
Feb 10 Javascript
JS+CSS实现六级网站导航主菜单效果
Sep 28 Javascript
Angular2 路由问题修复详解
Mar 01 Javascript
JavaScript实现为事件句柄绑定监听函数的方法分析
Nov 14 Javascript
JavaScript函数的特性与应用实践深入详解
Dec 30 Javascript
Vue中实现权限控制的方法示例
Jun 07 Javascript
微信小程序之数据绑定原理解析
Aug 14 Javascript
element-ui 远程搜索组件el-select在项目中组件化的实现代码
Dec 04 Javascript
js动态生成表格(节点操作)
Jan 12 Javascript
node.js实现简单的压缩/解压缩功能示例
Nov 05 #Javascript
js实现随机点名程序
Sep 17 #Javascript
vue+vant-UI框架实现购物车的复选框全选和反选功能
Nov 05 #Javascript
Vue通过WebSocket建立长连接的实现代码
Nov 05 #Javascript
原生js实现随机点名功能
Nov 05 #Javascript
element-ui 文件上传修改文件名的方法示例
Nov 05 #Javascript
vue keep-alive 动态删除组件缓存的例子
Nov 04 #Javascript
You might like
PHP的中问验证码
2006/11/25 PHP
PHP自定session保存路径及删除、注销与写入的方法
2014/11/18 PHP
浅谈Coreseek、Sphinx-for-chinaese、Sphinx+Scws的区别
2016/12/15 PHP
在php7中MongoDB实现模糊查询的方法详解
2017/05/03 PHP
一个非常实用的php文件上传类
2017/07/04 PHP
Windows下wamp php单元测试工具PHPUnit安装及生成日志文件配置方法
2018/05/28 PHP
BOOM vs RR BO5 第四场 2.14
2021/03/10 DOTA
ppk谈JavaScript style属性
2008/10/10 Javascript
jquery实现滑动图片自己测试的例子
2013/11/05 Javascript
node.js中的forEach()是同步还是异步呢
2015/01/29 Javascript
JavaScript中实现继承的三种方式和实例
2015/01/29 Javascript
优化RequireJS项目的相关技巧总结
2015/07/01 Javascript
JS模仿编辑器实时改变文本框宽度和高度大小的方法
2015/08/17 Javascript
jQuery EasyUI封装简化操作
2016/09/18 Javascript
Javascript中字符串相关常用的使用方法总结
2017/03/13 Javascript
jquery加载单文件vue组件的方法
2017/06/20 jQuery
使用Angular 6创建各种动画效果的方法
2018/10/10 Javascript
基于JavaScript实现每日签到打卡轨迹功能
2018/11/29 Javascript
如何用原生js写一个弹窗消息提醒插件
2019/05/24 Javascript
vue-cli配置全局sass、less变量的方法
2019/06/06 Javascript
vue设置导航栏、侧边栏为公共页面的例子
2019/11/01 Javascript
微信小程序修改checkbox的样式代码实例
2020/01/21 Javascript
python制作爬虫并将抓取结果保存到excel中
2016/04/06 Python
python基础之入门必看操作
2017/07/26 Python
Python实现JSON反序列化类对象的示例
2018/01/31 Python
python+selenium select下拉选择框定位处理方法
2019/08/24 Python
python中通过selenium简单操作及元素定位知识点总结
2019/09/10 Python
python程序中的线程操作 concurrent模块使用详解
2019/09/23 Python
使用Tensorflow实现可视化中间层和卷积层
2020/01/24 Python
Python实现钉钉/企业微信自动打卡的示例代码
2021/02/02 Python
英国豪华文具和皮具配件经典老品牌:Smythson(斯迈森)
2018/04/19 全球购物
Myprotein芬兰官网:欧洲第一运动营养品牌
2019/05/05 全球购物
运动会开幕式通讯稿
2015/07/18 职场文书
安全责任协议书范本
2016/03/23 职场文书
解决Swagger2返回map复杂结构不能解析的问题
2021/07/02 Java/Android
asyncio异步编程之Task对象详解
2022/03/13 Python