C罗上一篇文章由小程序下用户行为统计的一个问题谈起讲述了在统计用户行为过程中遇到的小程序自定义组件导致的事件转发问题,及对原有统计方案的冲击。本文将着重跟大家分享,页面中存在多组件、组件嵌套使用等情况如何在较少的改动前提下兼容旧有的方案。
旧方案与自定义组件结合归根结底要解决的核心问题如下
- 用户行为事件的捕获
- 用户行为标签的抽取
- 数据上报
如果能有效地解决以上问题,那么就可以与旧方案完美兼容。
先看下面2张图,图1是页面上未使用小程序自定义组件时的事件流模型,图2是应用自定义组件后的事件流模型。
乍一看,大哥,别逗我们了好吗?这么简单的dom事件模型也拿出来现眼,而且一样的图还绘制2遍?但这2张图是有很大的区别的,图1是正常的dom事件模型,在顶层容器上监听的事件具有全局把控性的,它通过事件对象清除地知道事件发生的target,并且能获取到dom节点的相应数据;而图2相较于图1的最大区别是,顶层容器收到的事件是通过最接近自己的自定义组件的shadow-root转发的,它只能知道该自定义组件中发生了自己监听的事件,但并不知道是自定组件中的具体哪个dom。
顶层容器代表2类老板:第1类老板,管理非常细致,每个人的任务进展情况都了如指掌,技术团队张三写了200行代码、李四写了300行代码全记在老板的小本本上;第2类老板,管理分层,听取技术leader的汇报,只知道技术团队一共产出500行代码,具体谁写了多少代码,交由技术leader去掌控。
但是,现在第2类老板心血来潮,想了解一下到底技术团队每个人的产出,该怎么办呢?技术leader拿出自己的小本本,张三200行代码、李四300行代码,详细地列出来发给老板,这样老板也就明白了,李四年底要多发500块奖金啦。
而我们要兼容旧方案的全局获取用户行为上报恰恰就像第2类老板,要详细知道真实发生事件的页面节点信息。
一起来看看部分示例代码:
组件最外层代码
<view bindtap="triggerAnalysis" bindanalysis="handleAnalysis">
...
</view>
为了兼容组件嵌套,组件自身需要具备处理自定义上报的能力以及自己抛出自定义上报的能力,所以定义组件时需要定义好。
小程序自定义组件的behaviors
module.exports = Behavior({
methods: {
// 处理监听到自定义上报事件
handleAnalysis(e) {
},
// 抛出自定义上报事件
triggerAnalysis(e) {
}
}
})
为避免每个组件都要去冗余书写自定义上报相关的逻辑,这个行为是所有组件都需要具备的,在自定义组件构造函数的基础上扩展出一个适合项目的类。
const analysis = require('../behaviors/analysis')
const defaultBehaviors = [analysis]
const WSComponent = function (params) {
if(Array.isArray(params.behaviors)){
defaultBehaviors.forEach(item => {
params.behaviors.push(item)
})
}else{
params.behaviors = defaultBehaviors
}
return Component(params)
}
通过扩展后,构造的自定义组件会具备额外的默认行为,而这种编程习惯也是cluo比较推荐的,AOP的方式,从全局去统一处理某类问题。
回顾整个问题的梳理与解决,涉及以下知识点(包含但不限于)
- Web Components
- Shadow dom事件转发
- 微信小程序自定义组件(包含组件行为)
- AOP编程思路
知其然知其所以然,欢迎与前端C罗讨论,拒绝吐槽,欢迎打赏!