页面交互行为跟踪
从 1.5.0 版本开始,amis 内置了跟踪用户交互行为采集功能。
使用方法
amis 只负责采集,对行为的存储和分析都需要外部实现。
在 amis 渲染时的第三个参数 env 可以传递 tracker 函数,下面以 sdk 作为示例,具体实现可以根据实际需求修改,比如可以收集一段时间后再批量提交等。
amis.embed('#root',{// amis schema},{// 这里是初始 props},{tracker: (eventTrack, props) => {const blob = new Blob([JSON.stringify(eventTrack)], {type: 'application/json'});navigator.sendBeacon('/tracker', blob);}});
参数类型
eventTrack 的类型定义是
interface EventTrack {// 后面会详细介绍eventType:| 'api'| 'url'| 'link'| 'dialog'| 'drawer'| 'copy'| 'reload'| 'email'| 'prev'| 'next'| 'cancel'| 'close'| 'submit'| 'confirm'| 'reset'| 'reset-and-submit'| 'formItemChange'| 'tabChange'| 'pageHidden'| 'pageVisible';/*** 事件数据,根据不同事件有不同结构,下面会详细说明*/eventData: ActionSchema | Api;}
有时候无法通过 eventData 区分点击行为,比如有个两个提交按钮
[{"label": "提交","primary": true},{"label": "提交","primary": true}]
当它触发事件的时 EventTrack 内容是一样的
{"eventType": "submit","eventData": {"primary": true,"label": "提交"}}
如何区分究竟是哪个事件?可以通过增加 id 属性,比如
[{"id": "button1","label": "提交","primary": true},{"id": "button2","label": "提交","primary": true}]
这样触发事件中就会包含 id 字段来方便区分,比如
{"eventType": "submit","eventData": {"id": "button1","primary": true,"label": "提交"}}
另一个方法是通过 tracker 的第二个参数 props 来判断,它可以拿到这个组件的所有属性配置
事件示例
除了下面的文档,还可以打开浏览器的控制台,在 debug 分类下可以看到实际操作时的例子
api
api 的来源有两方面,一个是各种组件的 api 及 source 配置,另一个是 action 里的 ajax 类型请求
以 crud 为例
{"eventType": "api","eventData": {"method": "get","url": "/api/mock2/sample?page=1&perPage=10","query": {"page": 1,"perPage": 10}}}
如果是 post 则类似下面的数据
{"eventType": "api","eventData": {"method": "post","url": "/api/mock2/form/saveForm"}}
为了避免信息泄露在 eventData 里没有包含提交数据,要获取提交数据详情需要通过第二个参数,参考下面的例子
{tracker: (eventTrack, data) => {console.log('提交数据详情', data);const blob = new Blob([JSON.stringify(eventTrack)], {type: 'application/json'});navigator.sendBeacon('/tracker', blob);};}
url
这是打开外部链接事件,注意不要和 link 混淆,link 一般用来做应用内相对地址无刷新跳转
示例
{"eventType": "url","eventData": {"url": "https://www.baidu.com","blank": true,"label": "百度一下,你就知道"}}
这个事件有可能是 Link 组件触发,也有可能是 Action 组件触发,如果是 Action 这是类似下面的参数
{"eventType": "url","eventData": {"url": "http://www.baidu.com","level": "success","blank": true,"label": "打开 Baidu"}}
Action 组件会多些数据
link
触发这个事件主要是 Action 和 Nav 组件
如果是 Action,数据将会是
{"eventType": "link","eventData": {"label": "进入介绍页","level": "info","link": "../index"}}
如果是 Nav,数据将会是
{"eventType": "link","eventData": {"label": "Nav 2-2","link": "?cat=2-2"}}
它们都有 label 及 link 字段
dialog
这个事件主要由 action 触发,示例
{"eventType": "dialog","eventData": {"dialog": {"title": "提示","closeOnEsc": true,"body": "这是个简单的弹框"},"label": "打开弹框"}}
需要注意 dialog 里会包含所有弹框的 schema 配置,可能会导致提交数据太大,建议根据需求裁剪。
drawer
这个事件主要由 action 触发,示例
{"eventType": "drawer","eventData": {"drawer": {"position": "left","size": "xs","title": "提示","body": "这是个简单的弹框"},"label": "左侧弹出-极小框"}}
和前面的 dialog 示例,它的数据中会包含所有 drawer 配置,可能会内容过大,需要根据需求过滤
copy
由 action 触发,示例如下
{"eventType": "copy","eventData": {"content": "http://www.baidu.com","label": "复制一段文本"}}
reload
由 action 触发,示例
{"eventType": "reload","eventData": {"label": "搜索","target": "my_form.select"}}
由 action 触发,示例
{"eventType": "email","eventData": {"to": "amis@baidu.com","cc": "baidu@baidu.com","subject": "这是邮件主题","body": "这是邮件正文","label": "发送邮件"}}
prev/next
可能有两个地方,一个是 Wizard 里的上一步下一步,还有可能是 Dialog 里的上一个下一个,示例
{"eventType": "next","eventData": {"level": "info","label": "下一个"}}
cancel
action 里的取消事件,示例
{"eventType": "cancel","eventData": {"label": "关闭"}}
close
action 里的关闭事件,主要用于关闭弹框,示例
{"eventType": "close","eventData": {"label": "算了"}}
submit
点击提交按钮的事件,这个事件可能还会同时触发 api 事件,比如表单的提交按钮。
{"eventType": "submit","eventData": {"primary": true,"label": "提交"}}
confirm
action 中的事件,主要用于关闭弹框
{"eventType": "confirm","eventData": {"primary": true,"label": "确认"}}
reset
由 action 触发,主要用于重置表单数据,示例
{"eventType": "reset","eventData": {"label": "重置"}}
reset-and-submit
由 action 触发,会重置表单并提交数据
{"eventType": "reset-and-submit","eventData": {"label": "重置并提交"}}
formItemChange
表单项数据变化时,也就是用户在表单里输入和修改任何数据时触发,比如
有一个特例是 input-password 类型的字段不会触发这个事件,避免隐私风险 但在 api 中还是有可能包含隐私信息,因此建议前面 api 类的事件不记录数据提交内容
{"eventType": "formItemChange","eventData": {"name": "name","label": "用户名","type": "input-text","value": "amis"}}
事件数据里主要是 name type 和 value
需要注意这个事件非常频繁,只要修改内容就会触发。
和 action 类似,如果给表单项加上 id 字段也会透传到这里,方便用于区分同名输入框,比如
{"eventType": "formItemChange","eventData": {"id": "name1","name": "name","label": "用户名","type": "input-text","value": "amis"}}
tabChange
tab 切换事件,示例
{"eventType": "tabChange","eventData": {"key": "tab2"}}
默认情况下 key 的值从 0 开始,如果 tab 上设置了 hash 值就会用这个值。
同样,如果 tabs 设置了 id,也会输出这个 id 值方便区分
pageHidden
当 tab 切换或者页面关闭时触发,可以当成用户离开页面的时间。
pageVisible
当用户又切换回当前页面的时间,可以当做是用户重新访问的开始时间。
由于 amis 可能被嵌入到页面中,所以 amis 无法知晓页面首次打开的时间,需要自行处理。
