更新记录

1.0.0(2026-07-27) 下载此版本

Sensors Wave 数据采集 SDK 正式发布

Changelog

Sensors Wave UniApp X 数据采集 SDK 的所有显著变更均记录于此文件。 格式参考 Keep a Changelog, 版本号遵循 Semantic Versioning

[1.0.0] - 2026-07-27

新增

  • Sensors Wave 数据采集 SDK 正式发布

平台兼容性

uni-app x(4.0)

Chrome Safari Android iOS 鸿蒙 微信小程序

其他

多语言 暗黑模式 宽屏模式
× ×

Sensorswave UniApp X 数据采集 SDK

Sensors Wave UniApp X 数据采集 SDK 是一个跨平台的数据埋点采集库,一套代码即可在多个平台自动采集用户行为数据。 以 uni-app-x 的 uni_modules 插件形态发布,业务工程通过 app.use(Sensorswave.plugin, config) 一行接入,应用级预置事件自动采集。 如果你是第一次接触 Sensors Wave,欢迎访问 sensorswave.com 了解产品并创建账号。

源码位于 uni_modules/sensorswave-uniappx/

特性

  • 🌐 跨平台支持:微信 / 支付宝 / 抖音 / 百度小程序、App(iOS / Android / 鸿蒙)、H5
  • 🔎 平台运行时探测:通过 uni.getSystemInfoSync() 自动识别宿主平台,无需手填 platformType / platformName
  • 🚀 应用级预置事件自动采集app.use() 后无需在 App.uvue 手动调用应用级生命周期方法
  • 📄 页面级预置事件:由 install() 注入的全局 mixin 统一驱动(H5 配合 vue-router.afterEach),业务页面零侵入
  • 👤 用户体系:匿名 / 登录用户标识、用户属性(profile)增删改、公共属性注册
  • 🧪 A/B 测试:功能开关(Feature Gate)、远程配置(Feature Config)、实验分组(Experiment)
  • 📡 UTM 追踪:自动解析启动参数中的 UTM 渠道参数并写入首值归因
  • 🔒 敏感字段脱敏:自定义事件属性中的敏感信息(token / password / cookie …)自动掩码
  • 💾 离线持久化:事件队列持久化存储、批量上报、失败重试,保障数据不丢
  • ♻️ 挂起离开恢复:进程被杀后下次启动自动补发未结束会话的离开事件

平台支持

平台 自动采集事件
微信小程序 $MPLaunch $MPShow $MPHide $MPPageView $MPPageLeave $MPShare
支付宝小程序 同微信小程序
抖音小程序 同微信小程序
百度小程序 同微信小程序
App iOS / Android / 鸿蒙 $AppStart $AppEnd $AppPageView $AppPageLeave $AppInstall
H5 $PageView $PageLeave $PageLoad $WebClick
  • 平台在运行时通过 uni.getSystemInfoSync() 自动识别,无需手动指定。
  • 所有平台上报事件的 $lib 预置属性统一为 uniappx,用于在数据端标识本采集 SDK。
  • $WebClick 需开启 enableClickTrack: true$MPShare 需开启 enableShareTrack(默认开启)。

安装

将本仓库的 uni_modules/sensorswave-uniappx/ 目录拷贝(或软链)到你的 UniApp X 工程的 uni_modules/ 下:

your-app/
└── uni_modules/
    └── sensorswave-uniappx/   ← 来自本仓库
        ├── package.json
        └── utssdk/

无需 npm 安装;uni-app-x 会自动识别 uni_modules 插件。

快速开始

推荐通过 Vue 插件 接入,插件会在 app.use() 时自动完成初始化,并注入页面生命周期 mixin,实现无侵入的页面浏览 / 离开采集。

1. 在 main.uts 安装插件

import App from './App.uvue'
import { createSSRApp } from 'vue'
import Sensorswave from '@/uni_modules/sensorswave-uniappx/utssdk/index'

export function createApp() {
  const app = createSSRApp(App)
  app.use(Sensorswave.plugin, {
    sourceToken: 'your_source_token', // 必填:数据源 Token
    apiHost: 'https://example.com',   // 必填:数据上报地址
    autoCapture: true,                // 自动采集生命周期(默认 true)
    enableClickTrack: true,           // 自动采集点击(默认 false)
    enableAB: true,                   // 启用 A/B 测试(默认 false)
    debug: false,                      // 调试日志(默认 false)
  })
  return { app }
}

2. App.uvue 无需手动调用应用级预置事件

应用级事件(启动 / 前后台切换 / 小程序分享)由 SDK 在 install() 内自动监听与触发, App.uvue 只需放置与业务身份相关的逻辑:

<script setup lang="uts">
import Sensorswave from '@/uni_modules/sensorswave-uniappx/utssdk/index'

onLaunch((options : any) => {
  // 仅在已登录场景下设置 loginId(可选)
  Sensorswave.setLoginId('user_123')
})
</script>

不需要调用 Sensorswave.onAppLaunch / onAppShow / onAppHide / onShare —— 它们会被自动触发。 页面级生命周期方法(onPageShow / onPageHide / onPageUnload)也不再对外暴露。

3. 页面级事件接入

通过 Vue 插件接入(推荐)后,页面级事件($PageView / $*PageLeave / $PageLoad)由 install() 注入的全局 mixin 统一驱动,业务页面零侵入

  • H5:全局 mixin + vue-router.afterEach 共同生效
  • 小程序 / App:全局 mixin 合并到 App 根组件、页面及所有自定义组件,SDK 内部通过 $scope.route / $page.route / $options.mpType === 'page' 过滤出真正的页面实例,避免 App 根组件 / 子组件的 onShow 误触发 $MPPageView / $AppPageView

备选方案:如果你直接调用 Sensorswave.init(sourceToken, config)(不走 app.use()),没有 app 实例注册全局 mixin,需要在每个页面手动集成:

<script setup>(推荐)

<script setup lang="uts">
import { useSensorswavePageLifecycle } from '@/uni_modules/sensorswave-uniappx/utssdk/index'

useSensorswavePageLifecycle()
</script>

Options API

import { SensorswavePageMixin } from '@/uni_modules/sensorswave-uniappx/utssdk/index'
export default {
  mixins: [SensorswavePageMixin],
}

4. 在组件中调用

插件安装后,SDK 实例会挂载到 Vue 全局属性 $sensorswave

  • Options API:可通过 this.$sensorswave 访问。
  • <script setup>:没有 this,直接 import Sensorswave 调用单例即可(推荐)。

无论哪种写法,拿到的是同一个 SDK 单例,调用方式完全一致。

import Sensorswave from '@/uni_modules/sensorswave-uniappx/utssdk/index'

// 自定义事件(推荐:使用 trackEvent)
Sensorswave.trackEvent('button_click', { button_name: 'submit', amount: 99 })

⚠️ sourceTokenapiHost 为必填项,缺失会导致数据无法上报(SDK 会在控制台输出告警)。

配置项

配置 类型 默认值 说明
sourceToken string '' 必填。数据上报凭证,由服务端分配
apiHost string '' 必填。数据上报 API 地址
debug boolean false 是否开启调试模式,输出详细日志
autoCapture boolean true 是否自动采集生命周期事件(启动、前后台、页面浏览等)
batchSend boolean false 是否启用批量发送(关闭则即时发送)
maxBatchSize number 10 批量发送时每批最大事件数
flushInterval number 5000 批量发送轮询间隔(毫秒)
enableClickTrack boolean false 是否自动采集元素点击($WebClick),仅 H5 支持
enableShareTrack boolean true 是否自动采集小程序分享(仅 MP)
enableAB boolean false 是否启用 A/B 测试功能
abRefreshInterval number 600000 A/B 测试缓存刷新间隔(毫秒,默认 10 分钟,最小 30 秒)

API 方法

事件追踪

trackEvent(eventName, properties?)

手动上报一个自定义事件。时间戳默认取当前时刻。

  • eventName(string,必填):事件名称
  • properties(object,可选):事件属性
Sensorswave.trackEvent('OrderSubmit', {
  order_id: 'ORDER_001',
  amount: 99.9,
  currency: 'CNY',
})

track - 高级事件追踪

发送完整的事件对象,支持更精细的控制。此方法允许您手动指定所有事件字段。

参数

  • event (必填):完整事件对象,包含以下字段:
    • event (string,必填):事件名称
    • properties (Record<string, any>,可选):事件属性
    • time (number,可选):时间戳(毫秒),缺省时 SDK 取当前时刻
    • anon_id (string,可选):匿名用户 ID,缺省时从 store 读取
    • login_id (string,可选):登录用户 ID。login_idanon_id 至少传一个;都传时优先 login_id;都缺省时从 store 兜底
    • trace_id (string,可选):请求追踪 ID,缺省时 SDK 自动生成 UUID
    • user_properties (Record<string, any>,可选):用户属性,透传

示例

Sensorswave.track({
  event: 'purchaseCompleted',
  properties: {
    product_id: '12345',
    amount: 99.99,
    currency: 'USD'
  },
  time: Date.now(),
  trace_id: 'unique-trace-id-12345',
  anon_id: 'anonymous-user-id',
  login_id: 'user_12345',
  user_properties: {
    // $set: 代表插入或者更新一条用户属性信息
    $set: {
      plan: 'premium',
      signup_date: '2024-01-01'
    }
  }
});

// 也可只传 event 名称,其余字段由 SDK 兜底
Sensorswave.track({ event: 'OrderPaid' });

💡 普通业务事件请优先使用 trackEvent,仅在需要精确控制 time / trace_id / user_properties 等字段时使用 track

用户标识

identify(loginId)

设置登录 ID,并发送 $Identify 事件,将匿名行为与登录用户关联。

Sensorswave.identify('user_12345')

setLoginId(loginId)

设置登录 ID,发送 $Identify 事件。仅需要标识用户、不需要追踪关联事件时使用。

Sensorswave.setLoginId('user_12345')

getLoginId()

获取当前登录用户 ID,未登录或未初始化时返回空字符串。返回 string

const loginId = Sensorswave.getLoginId()

getAnonId()

获取当前匿名用户 ID,该 ID 在设备首次使用时自动生成并持久化。返回 string

const anonId = Sensorswave.getAnonId()

用户属性(Profile)

profileSet(properties)

设置用户属性,已存在的属性会被覆盖。

Sensorswave.profileSet({
  name: 'alice',
  age: 30,
  plan: 'premium',
})

profileSetOnce(properties)

首次设置用户属性,已存在的属性不会被覆盖。常用于记录首次注册时间、首次来源等。

Sensorswave.profileSetOnce({
  signup_date: '2026-01-15',
  initial_referrer: 'google',
})

profileIncrement(properties)

对数值型用户属性进行递增操作,仅支持数值类型,支持正数和负数。

// 递增单个属性
Sensorswave.profileIncrement({ login_count: 1 })

// 递增多个属性
Sensorswave.profileIncrement({
  login_count: 1,
  points_earned: 100,
})

profileAppend(properties)

向数组类型的用户属性追加元素,不去重

Sensorswave.profileAppend({
  categories_viewed: ['electronics', 'mobile_phones'],
})

profileUnion(properties)

向数组类型的用户属性追加元素,自动去重

Sensorswave.profileUnion({
  interests: ['technology', 'gaming'],
})

profileUnset(keys)

删除指定的用户属性。

  • keys(string[],必填):要删除的属性名数组
// 删除单个属性
Sensorswave.profileUnset(['temporary_campaign'])

// 删除多个属性
Sensorswave.profileUnset(['old_plan', 'expired_flag'])

profileDelete()

删除当前用户的全部用户属性数据,操作不可恢复。仅对已登录用户有效。

Sensorswave.profileDelete()

公共属性

公共属性会自动附加到后续上报的所有事件上,适合注入全局上下文(如应用版本、环境等)。 值支持静态值(字符串 / 数值 / 布尔等),也支持动态函数——函数会在每次事件构建时调用取最新值, 例如 now: () => Date.now()$screen: () => getCurrentPage().route 等场景都能正确取到当前时刻 / 当前页。

registerCommonProperties(properties)

注册公共属性,已存在的同名属性会被覆盖。

// 静态公共属性
Sensorswave.registerCommonProperties({
  app_version: '1.0.0',
  environment: 'production',
  app_channel: 'wechat',
})

// 动态公共属性:每次事件上报时实时求值
Sensorswave.registerCommonProperties({
  $current_time: () => Date.now(),
  $active_page: () => getCurrentPages().pop()?.route ?? '',
})

clearCommonProperties(keys?)

清除已注册的公共属性。不传 keys 时清除全部。

// 清除指定公共属性
Sensorswave.clearCommonProperties(['app_version', 'app_channel'])

// 清除全部公共属性
Sensorswave.clearCommonProperties()

A/B 测试

需在初始化时设置 enableAB: true,否则以下方法将直接返回默认值。

checkFeatureGate(key)

检查功能开关(Feature Gate)是否对当前用户开启。返回 Promise<boolean>

const enabled = await Sensorswave.checkFeatureGate('new_checkout_flow')
if (enabled) {
  showNewCheckout()
}

getFeatureConfig(key)

获取远程配置(Feature Config)。服务端返回的 JSON 字符串会被自动解析。返回 Promise<Record<string, any>>,未启用 A/B 测试时返回空对象 {}

const config = await Sensorswave.getFeatureConfig('app_settings')
const { theme, layout } = config

getExperiment(key)

获取实验分组(Experiment)。返回 Promise<Record<string, any>>,未命中实验或未启用 A/B 测试时返回空对象。

const exp = await Sensorswave.getExperiment('homepage_layout')
const { layout_type } = exp

其他

isInitialized()

查询 SDK 是否已完成初始化。返回 boolean。与只读属性 isInited 等价。

if (Sensorswave.isInitialized()) {
  Sensorswave.trackEvent('Ready')
}

isInited

只读属性,判断 SDK 是否已完成初始化。未初始化时为 false

if (Sensorswave.isInited) {
  Sensorswave.trackEvent('Ready')
}

init(sourceToken, config?)

手动初始化 SDK(不使用 Vue 插件)。sourceToken 作为独立参数传入。

⚠️ 直接调用 init() 不会注入页面生命周期 mixin,因此页面浏览 / 离开的自动采集将失效。 仅在你不需要自动页面采集、或希望完全控制初始化时机时使用。

Sensorswave.init('your_source_token', {
  apiHost: 'https://example.com',
  autoCapture: true,
})

destroy()

销毁 SDK 实例:停止批量发送器、销毁所有插件、移除全部事件监听器并重置为未初始化状态。销毁后可重新 init() 或再次 app.use() 安装。

Sensorswave.destroy()

自动采集事件

开启 autoCapture(默认开启)后,SDK 会根据运行平台自动注册对应采集器:

  • 小程序:启动、显示 / 隐藏、页面浏览 / 离开(由全局 mixin 驱动)、(默认)分享
  • App:启动 / 退出(后台满 30s 才触发 $AppEnd,30s 内回前台视为同会话)、首次安装、UTM 首值归因($UserSet)、页面浏览 / 离开(由全局 mixin 驱动)
  • H5:页面浏览、页面加载性能、页面离开、(可选)点击

页面浏览 / 离开采集通过 install() 注入的全局 mixin 统一驱动(onLoad / onShow / onHide / onUnload),业务页面零侵入——这是 Vue 插件的标准用法。直接调 init()(不走插件)时无 app 实例,需要改用手动集成,见上方「页面级事件接入」小节。

预置事件一览

事件 平台 触发时机
$MPLaunch 小程序 启动(自动)
$AppStart App 启动 / 从后台回前台(自动;30s 内回前台不发)
$AppInstall App 首次启动(自动)
$MPShow 小程序 进入前台(自动)
$MPHide 小程序 进入后台(自动,即时上报)
$AppEnd App 进入后台满 30s(自动)
$MPPageView 小程序 页面显示(全局 mixin 自动)
$AppPageView App 页面显示(全局 mixin 自动)
$PageView H5 页面显示(全局 mixin + vue-router 自动)
$MPPageLeave 小程序 页面离开 / 卸载(全局 mixin 自动,含 $event_duration
$AppPageLeave App 页面离开 / 卸载(全局 mixin 自动,含 $event_duration
$PageLeave H5 页面离开 / 卸载(自动,含 $event_duration
$PageLoad H5 页面加载性能(自动)
$WebClick H5 元素点击(需 enableClickTrack: true
$MPShare 小程序 用户分享(自动包裹 onShareAppMessage
$Identify 全部 identify()
$UserSet 全部 UTM 首值归因(每次启动 + 首次拿到非空 UTM 时自动发,含 5 个 UTM 键)
$FeatureImpress / $ExpImpress 全部 A/B 曝光(自动,含 user_properties: $feature_/ $exp_ 命中赋值或未命中清空)

预置属性

SDK 会自动采集一系列以 $ 开头的预置属性并附加到每个事件,包括:

  • 设备 / 系统$lib(固定 uniappx)、$lib_version$model$os$os_version$screen_width$screen_height$timezone_offset$language
  • 小程序特有$brand$manufacturer$network_type$scene
  • App 特有$brand$manufacturer$device_id$wifi$app_version$app_id$app_name$region$network_type
  • H5 特有$browser$browser_version$viewport_width$viewport_height
  • 页面信息$url$url_path$url_query$title$referrer(H5 另有 $host$pathname$referrer_host$search_engine
  • UTM 渠道utm_sourceutm_mediumutm_campaignutm_contentutm_term

⚠️ $ 前缀为系统保留,自定义事件属性请勿使用 $ 前缀,以免与预置属性冲突。

数据安全

  • 自定义事件属性脱敏tokenpasswordsecretcookiesession_idapi_key 等 17 类敏感关键词命中的字段,其值在发送前自动掩码为 ***(保留键名,仅丢弃值)。
  • URL 查询参数脱敏$url_query 中的敏感参数会被整体剔除。

鸿蒙适配

App 鸿蒙端需要声明网络与网络信息相关权限,否则事件数据无法上报、$network_type 等属性无法正常采集:

// entry/src/main/module.json5
{
  "module": {
    "requestPermissions": [
      { "name": "ohos.permission.INTERNET" },
      { "name": "ohos.permission.GET_NETWORK_INFO" }
    ]
  }
}

⚠️ 关键说明:必须配置 ohos.permission.GET_NETWORK_INFO 权限才能正确获取网络信息

鸿蒙平台上,SDK 通过 uni.getNetworkType() 获取当前网络类型以采集 $network_type 预置属性。若未声明 ohos.permission.GET_NETWORK_INFO 权限,uni.getNetworkType() 将调用失败,导致 $network_type 始终为空。这是鸿蒙端正确获取网络信息的前提,请务必在 module.json5 中声明该权限。

各权限作用:

  • ohos.permission.INTERNET:保证事件数据能正常上报
  • ohos.permission.GET_NETWORK_INFO:保证 $network_type 能正确获取

许可

Apache-2.0

隐私、权限声明

1. 本插件需要申请的系统权限列表:

android.permission.INTERNET

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

本插件会采集终端用户行为数据并上报至开发者配置的服务端

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

许可协议

MIT协议