gio-miniprogram-sdk 4.0.0 → 4.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/alipay.js +1 -1
- package/dist/baidu.js +1 -1
- package/dist/bytedance.js +1 -1
- package/dist/jingdong.js +1 -1
- package/dist/kuaishou.js +1 -1
- package/dist/plugins/gioImpressionTracking.js +1 -1
- package/dist/qq.js +1 -1
- package/dist/quickapp.js +1 -1
- package/dist/taobao.js +1 -1
- package/dist/taro.js +1 -1
- package/dist/uniapp.js +1 -1
- package/dist/wechat.js +1 -1
- package/package.json +1 -1
- package/src/constants/config.ts +2 -2
- package/src/constants/regex.ts +15 -0
- package/src/core/dataStore/index.ts +8 -1
- package/src/core/growingIO.ts +1 -2
- package/src/core/uploader.ts +2 -7
- package/src/pluginsOut/frameworks/gioTaobaoAdapter.ts +0 -1
- package/src/pluginsOut/frameworks/gioTaroAdapter.ts +291 -190
- package/src/pluginsOut/ordinary/gioImpressionTracking.ts +56 -21
- package/src/types/base.ts +2 -0
- package/src/types/eventHooks.ts +3 -3
- package/src/types/uploader.ts +0 -2
- package/src/pluginsOut/README.md +0 -50
package/src/constants/config.ts
CHANGED
|
@@ -29,8 +29,8 @@ export const DEFAULT_SETTINGS = {
|
|
|
29
29
|
performance: { type: 'object', default: { monitor: true, exception: true } },
|
|
30
30
|
// 数据上报域名
|
|
31
31
|
serverUrl: { type: 'string', default: 'https://napi.growingio.com' },
|
|
32
|
-
//
|
|
33
|
-
|
|
32
|
+
// 请求超时时长
|
|
33
|
+
requestTimeout: { type: 'number', default: 5000 },
|
|
34
34
|
// taro框架实例
|
|
35
35
|
taro: { type: ['object', 'module'], default: false },
|
|
36
36
|
// taro框架vue实例
|
package/src/constants/regex.ts
CHANGED
|
@@ -2,3 +2,18 @@ export const IPReg =
|
|
|
2
2
|
/^((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})(\.((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})){3}/i;
|
|
3
3
|
export const URLReg =
|
|
4
4
|
/^(https?:\/\/)|(([a-zA-Z0-9_-])+(\.)?)*(:\d+)?(\/((\.)?(\?)?=?&?[a-zA-Z0-9_-](\?)?)*)*$/i;
|
|
5
|
+
export const UNIAPP_FUNC_REG = /^e[0-9]+$/;
|
|
6
|
+
export const ABTEST_SIGN_REG = /^\d+_gdp_abt_sign$/;
|
|
7
|
+
export const ABTEST_DATA_REG = /^\d+_gdp_abtd$/;
|
|
8
|
+
export const ID_REG = /^\d{1,10}$/;
|
|
9
|
+
export const IMP_DATA_REG = /^gioTrack(.+)/;
|
|
10
|
+
export const IMP_EVENTNAME_REG = /^[a-zA-Z_][0-9a-zA-Z_]{0,100}$/;
|
|
11
|
+
export const QUICKAPP_PARAM_REG = /^text.*/;
|
|
12
|
+
export const SWAN_XID_REG = /^_[0-9a-z]+/;
|
|
13
|
+
export const TARO_XID_REG = /^_n_[0-9]+$/;
|
|
14
|
+
export const TARO_EVENT_PROPS_REG = /^__reactProps\$[a-z0-9]+$/i;
|
|
15
|
+
export const TARO_EVENT_REACT_FUNC1_REG = /return [$\w]+.\w+\(/;
|
|
16
|
+
export const TARO_EVENT_REACT_FUNC2_REG = /return \w+\(/;
|
|
17
|
+
export const TARO_EVENT_VUE_FUNC1_REG = /return [$\w]+.\$emit\(['"]\w+/;
|
|
18
|
+
export const TARO_EVENT_VUE_FUNC2_REG = /return [$\w]+.\w+/;
|
|
19
|
+
export const TARO_EVENT_VUE_FUNC3_REG = /return [$\w]+/;
|
|
@@ -68,6 +68,7 @@ class DataStore implements DataStoreType {
|
|
|
68
68
|
constructor(public growingIO: GrowingIOType) {
|
|
69
69
|
this.initStorageInfo();
|
|
70
70
|
this.eventContextBuilder = new EventContextBuilder(this.growingIO).main;
|
|
71
|
+
this.eventHooks = new EventHooks(this.growingIO);
|
|
71
72
|
this.shareOut = false;
|
|
72
73
|
this.lastVisitEvent = {};
|
|
73
74
|
this.lastPageEvent = {};
|
|
@@ -75,7 +76,6 @@ class DataStore implements DataStoreType {
|
|
|
75
76
|
this.generalProps = {};
|
|
76
77
|
this.trackTimers = {};
|
|
77
78
|
this.interceptEvents = [];
|
|
78
|
-
this.eventHooks = new EventHooks(this.growingIO);
|
|
79
79
|
// visit、page事件监听
|
|
80
80
|
this.growingIO.emitter.on('onComposeAfter', ({ composedEvent }) => {
|
|
81
81
|
if (composedEvent.eventType === 'VISIT' || composedEvent.t === 'vst') {
|
|
@@ -244,6 +244,13 @@ class DataStore implements DataStoreType {
|
|
|
244
244
|
if (vdsConfig.pluginMode) {
|
|
245
245
|
this.growingIO.inPlugin = true;
|
|
246
246
|
}
|
|
247
|
+
// 请求超时时长设置的合法区间校验,值小于等于0ms认为不合法,改回5秒,浏览器默认有2分钟的上限
|
|
248
|
+
if (
|
|
249
|
+
isNaN(Number(vdsConfig.requestTimeout)) ||
|
|
250
|
+
vdsConfig.requestTimeout <= 0
|
|
251
|
+
) {
|
|
252
|
+
vdsConfig.requestTimeout = 5000;
|
|
253
|
+
}
|
|
247
254
|
this.growingIO.vdsConfig = {
|
|
248
255
|
...vdsConfig,
|
|
249
256
|
projectId,
|
package/src/core/growingIO.ts
CHANGED
|
@@ -306,8 +306,7 @@ class GrowingIO implements GrowingIOType {
|
|
|
306
306
|
...attributes,
|
|
307
307
|
event_duration: tracker.leng > maxEnd ? 0 : tracker.leng / 1000
|
|
308
308
|
}),
|
|
309
|
-
...eventContextBuilder()
|
|
310
|
-
customEventType: 0
|
|
309
|
+
...eventContextBuilder()
|
|
311
310
|
};
|
|
312
311
|
eventInterceptor(event);
|
|
313
312
|
this.removeTimer(timerId);
|
package/src/core/uploader.ts
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
|
-
endsWith,
|
|
3
2
|
isArray,
|
|
4
3
|
isEmpty,
|
|
5
4
|
startsWith,
|
|
6
5
|
throttle,
|
|
7
|
-
toString,
|
|
8
6
|
unset
|
|
9
7
|
} from '@@/utils/glodash';
|
|
10
8
|
import { Event } from '@@/types/base';
|
|
@@ -19,8 +17,6 @@ class Uploader implements UploaderType {
|
|
|
19
17
|
public requestQueue: any[];
|
|
20
18
|
// 请求限制最大数
|
|
21
19
|
public requestLimit: number;
|
|
22
|
-
// 请求超时时间(ms)
|
|
23
|
-
public requestTimeout: number;
|
|
24
20
|
// 请求重试限制最大数
|
|
25
21
|
public retryLimit: number;
|
|
26
22
|
// 请求重试的原请求id
|
|
@@ -34,7 +30,6 @@ class Uploader implements UploaderType {
|
|
|
34
30
|
this.hoardingQueue = [];
|
|
35
31
|
this.requestQueue = [];
|
|
36
32
|
this.requestLimit = 3;
|
|
37
|
-
this.requestTimeout = 5000;
|
|
38
33
|
this.retryLimit = 2;
|
|
39
34
|
this.retryIds = {};
|
|
40
35
|
this.requestingNum = 0;
|
|
@@ -95,10 +90,10 @@ class Uploader implements UploaderType {
|
|
|
95
90
|
this.hoardingQueue = this.hoardingQueue.slice(50);
|
|
96
91
|
} else {
|
|
97
92
|
// 如果积压队列小于50,正常的请求队列就只截取补满50后剩下的事件
|
|
98
|
-
this.hoardingQueue = [];
|
|
99
93
|
this.requestQueue = this.requestQueue.slice(
|
|
100
94
|
50 - this.hoardingQueue.length
|
|
101
95
|
);
|
|
96
|
+
this.hoardingQueue = [];
|
|
102
97
|
}
|
|
103
98
|
} else {
|
|
104
99
|
this.hoardingQueue = [];
|
|
@@ -168,7 +163,7 @@ class Uploader implements UploaderType {
|
|
|
168
163
|
header,
|
|
169
164
|
method: 'POST',
|
|
170
165
|
data: compressData,
|
|
171
|
-
timeout:
|
|
166
|
+
timeout: vdsConfig.requestTimeout,
|
|
172
167
|
fail: (result: any) => {
|
|
173
168
|
if (![200, 204].includes(result.code)) {
|
|
174
169
|
if (isArray(eventsQueue)) {
|
|
@@ -3,35 +3,47 @@
|
|
|
3
3
|
* 用途:用于重写Taro框架下的创建App/Page/Component方法实现代理Hook;并获取Taro框架下的自定义方法真实方法名获取。
|
|
4
4
|
* 注意:测试taro3react时,微信要用react18测试,支付宝要用react17测试。
|
|
5
5
|
*/
|
|
6
|
+
import {
|
|
7
|
+
TARO_EVENT_PROPS_REG,
|
|
8
|
+
TARO_EVENT_REACT_FUNC1_REG,
|
|
9
|
+
TARO_EVENT_REACT_FUNC2_REG,
|
|
10
|
+
TARO_EVENT_VUE_FUNC1_REG,
|
|
11
|
+
TARO_EVENT_VUE_FUNC2_REG,
|
|
12
|
+
TARO_EVENT_VUE_FUNC3_REG
|
|
13
|
+
} from '@@/constants/regex';
|
|
6
14
|
import { GrowingIOType } from '@@/types/growingIO';
|
|
7
15
|
|
|
8
16
|
let ut;
|
|
17
|
+
const HANDLER = {
|
|
18
|
+
tap: 'onClick',
|
|
19
|
+
longpress: 'onLongPress'
|
|
20
|
+
};
|
|
21
|
+
const CUSTOM_HOOK_EVENTS = [
|
|
22
|
+
'onShareAppMessage',
|
|
23
|
+
'onShareTimeline',
|
|
24
|
+
'onAddToFavorites',
|
|
25
|
+
'onTabItemTap'
|
|
26
|
+
];
|
|
9
27
|
class GioTaroAdapter {
|
|
28
|
+
public taroVersion: string;
|
|
10
29
|
private taro: any;
|
|
11
|
-
private
|
|
30
|
+
private taroVue: any;
|
|
31
|
+
private taroVueVersion: number;
|
|
12
32
|
private exposedNames: any;
|
|
13
|
-
private taro3Listeners: any;
|
|
14
33
|
constructor(public growingIO: GrowingIOType) {
|
|
15
|
-
const { utils,
|
|
16
|
-
this.growingIO;
|
|
34
|
+
const { utils, emitter, minipInstance } = this.growingIO;
|
|
17
35
|
ut = utils;
|
|
18
|
-
this.taro = vdsConfig?.taro;
|
|
19
|
-
this.vue = vdsConfig?.taroVue;
|
|
20
36
|
this.exposedNames = {};
|
|
21
|
-
this.taro3Listeners = {};
|
|
22
37
|
emitter.on('minipLifecycle', ({ event }) => {
|
|
23
|
-
if (
|
|
24
|
-
if (this.taro &&
|
|
38
|
+
if (['Page onShow', 'Page onReady'].includes(event)) {
|
|
39
|
+
if (this.taro && this.taroVersion === '3') {
|
|
25
40
|
// 提前存储页面节点信息用来获取dataset
|
|
26
|
-
this.
|
|
41
|
+
this.saveFullPage(document.body);
|
|
27
42
|
// taro3开发时要等onready才能取到节点,所以补充做一次曝光监听
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
0
|
|
33
|
-
);
|
|
34
|
-
}
|
|
43
|
+
setTimeout(
|
|
44
|
+
() => minipInstance.initImpression(minipInstance.getCurrentPage()),
|
|
45
|
+
0
|
|
46
|
+
);
|
|
35
47
|
}
|
|
36
48
|
}
|
|
37
49
|
});
|
|
@@ -39,18 +51,31 @@ class GioTaroAdapter {
|
|
|
39
51
|
|
|
40
52
|
// 主入口,版本判断
|
|
41
53
|
main = () => {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
if (!Current && createComponent) {
|
|
54
|
+
const { taro, taroVue } = this.growingIO.vdsConfig;
|
|
55
|
+
const { Current, createComponent } = taro;
|
|
56
|
+
const isTaro2 = !Current && createComponent;
|
|
57
|
+
const isTaro3 = Current && !createComponent;
|
|
58
|
+
this.taro = taro;
|
|
59
|
+
if (isTaro2) {
|
|
60
|
+
// taro2
|
|
61
|
+
this.taroVersion = '2';
|
|
51
62
|
this.proxyTaro2(this.taro);
|
|
52
|
-
|
|
53
|
-
|
|
63
|
+
ut.consoleText('Taro version 2', 'info');
|
|
64
|
+
} else if (isTaro3) {
|
|
65
|
+
// taro3
|
|
66
|
+
this.taroVersion = '3';
|
|
67
|
+
this.taroVue = taroVue;
|
|
68
|
+
if (this.taroVue) {
|
|
69
|
+
const mainVersion = Number.parseInt(
|
|
70
|
+
ut.head(ut.split(this.taroVue.version, '.')),
|
|
71
|
+
10
|
|
72
|
+
);
|
|
73
|
+
this.taroVueVersion = mainVersion;
|
|
74
|
+
ut.consoleText(`Taro version 3, Vue version ${mainVersion}`, 'info');
|
|
75
|
+
} else {
|
|
76
|
+
ut.consoleText('Taro version 3', 'info');
|
|
77
|
+
}
|
|
78
|
+
this.proxyTaro3();
|
|
54
79
|
} else {
|
|
55
80
|
ut.consoleText('未获取到Taro实例或不支持的Taro版本,请检查!', 'error');
|
|
56
81
|
}
|
|
@@ -106,44 +131,50 @@ class GioTaroAdapter {
|
|
|
106
131
|
};
|
|
107
132
|
|
|
108
133
|
// 代理taro3
|
|
109
|
-
proxyTaro3 = (
|
|
110
|
-
const { eventHooks } = this.growingIO.dataStore;
|
|
111
|
-
if (vue) {
|
|
112
|
-
console.log('Vue version: ', vue.version);
|
|
113
|
-
const mainVersion = Number.parseInt(
|
|
114
|
-
ut.head(ut.split(vue.version, '.')),
|
|
115
|
-
10
|
|
116
|
-
);
|
|
117
|
-
eventHooks.nativeGrowing();
|
|
118
|
-
if (mainVersion === 2) {
|
|
119
|
-
this.taro3Vue2Proxy(vue);
|
|
120
|
-
} else if (mainVersion === 3) {
|
|
121
|
-
this.taro3Vue3Proxy(vue);
|
|
122
|
-
} else {
|
|
123
|
-
ut.consoleText('不支持的Vue版本,请使用 Vue2 或 Vue3!', 'error');
|
|
124
|
-
}
|
|
125
|
-
} else {
|
|
126
|
-
eventHooks.nativeGrowing(['App']);
|
|
127
|
-
this.taro3ReactProxy(taro);
|
|
128
|
-
}
|
|
129
|
-
};
|
|
130
|
-
|
|
131
|
-
// taro3使用react的代理
|
|
132
|
-
taro3ReactProxy = (taroRuntime: any) => {
|
|
133
|
-
// @ts-ignore
|
|
134
|
-
const taroNode = document.__proto__.__proto__;
|
|
134
|
+
proxyTaro3 = () => {
|
|
135
135
|
const self = this;
|
|
136
|
-
const {
|
|
137
|
-
|
|
138
|
-
|
|
136
|
+
const {
|
|
137
|
+
dataStore: { eventHooks },
|
|
138
|
+
minipInstance
|
|
139
|
+
} = this.growingIO;
|
|
140
|
+
// hook app
|
|
141
|
+
eventHooks.nativeGrowing(['App']);
|
|
142
|
+
// taro3vue2走单独的hook逻辑
|
|
143
|
+
if (this.taroVueVersion === 2) {
|
|
144
|
+
eventHooks.nativeGrowing(['Page']);
|
|
145
|
+
this.taro3Vue2Proxy();
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
if (this.taroVueVersion === 3) {
|
|
149
|
+
this.proxyTaro3vue3();
|
|
150
|
+
}
|
|
151
|
+
// taro3react / taro3vue3走监听hook逻辑
|
|
152
|
+
const originCall = self.taro?.hooks?.call;
|
|
139
153
|
if (originCall) {
|
|
140
|
-
self.defineProperty(
|
|
154
|
+
self.defineProperty(self.taro.hooks, 'call', function (...args) {
|
|
141
155
|
const argsArray = Array.from(args);
|
|
142
156
|
let result = originCall.apply(this, argsArray);
|
|
157
|
+
// 根据taro消息直接触发页面生命周期
|
|
158
|
+
if (argsArray[0] === 'getLifecycle') {
|
|
159
|
+
const lifetime = argsArray[2];
|
|
160
|
+
if (
|
|
161
|
+
eventHooks.pageHandlers.includes(lifetime) &&
|
|
162
|
+
!CUSTOM_HOOK_EVENTS.includes(lifetime)
|
|
163
|
+
) {
|
|
164
|
+
ut.niceTry(() =>
|
|
165
|
+
eventHooks.pageEffects.main(
|
|
166
|
+
minipInstance.getCurrentPage(),
|
|
167
|
+
lifetime,
|
|
168
|
+
argsArray[1]
|
|
169
|
+
)
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
// 分享和添加收藏事件走hook逻辑
|
|
143
174
|
if (argsArray[0] === 'modifyPageObject') {
|
|
144
175
|
const pageObject = argsArray[1];
|
|
145
|
-
|
|
146
|
-
if (
|
|
176
|
+
CUSTOM_HOOK_EVENTS.forEach((k) => {
|
|
177
|
+
if (pageObject[k]) {
|
|
147
178
|
pageObject[k] = eventHooks.lifeFcEffects(
|
|
148
179
|
k,
|
|
149
180
|
ut.isFunction(pageObject[k]) ? pageObject[k] : () => {},
|
|
@@ -152,49 +183,217 @@ class GioTaroAdapter {
|
|
|
152
183
|
}
|
|
153
184
|
});
|
|
154
185
|
}
|
|
186
|
+
// 无埋点事件
|
|
187
|
+
if (argsArray[0] === 'dispatchTaroEvent') {
|
|
188
|
+
const taroEvent = argsArray[1];
|
|
189
|
+
const taroElement = argsArray[2];
|
|
190
|
+
const actionEffects =
|
|
191
|
+
self.growingIO.plugins?.gioEventAutoTracking?.main;
|
|
192
|
+
if (
|
|
193
|
+
ut.isFunction(actionEffects) &&
|
|
194
|
+
eventHooks.actionEventTypes.includes(taroEvent.type)
|
|
195
|
+
) {
|
|
196
|
+
const { currentTarget, target, detail } = taroEvent.mpEvent;
|
|
197
|
+
// taro本身会给所有节点添加id,id一致说明是触发事件的节点
|
|
198
|
+
if (target.id === currentTarget.id) {
|
|
199
|
+
// 尝试获取真实的方法名
|
|
200
|
+
try {
|
|
201
|
+
let originHandler = ut.head(
|
|
202
|
+
taroElement.__handlers[taroEvent.type]
|
|
203
|
+
);
|
|
204
|
+
// 一定要有对应的事件
|
|
205
|
+
if (originHandler) {
|
|
206
|
+
if (originHandler.oldHandler) {
|
|
207
|
+
originHandler = originHandler.oldHandler;
|
|
208
|
+
}
|
|
209
|
+
let funcName = '';
|
|
210
|
+
if (self.taroVue) {
|
|
211
|
+
// vue3
|
|
212
|
+
funcName = self.taro3vue3GetFuncName(
|
|
213
|
+
originHandler,
|
|
214
|
+
taroElement
|
|
215
|
+
);
|
|
216
|
+
} else {
|
|
217
|
+
// react --- @tarojs/runtime 3.6.x会有一个随机名的对象存储点击事件优先获取,其他版本直接取originHandler
|
|
218
|
+
funcName = self.taro3reactGetFuncName(
|
|
219
|
+
originHandler,
|
|
220
|
+
taroEvent,
|
|
221
|
+
taroElement
|
|
222
|
+
);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// 构建无埋点事件
|
|
226
|
+
actionEffects(
|
|
227
|
+
{
|
|
228
|
+
...taroEvent.mpEvent,
|
|
229
|
+
currentTarget: {
|
|
230
|
+
...currentTarget,
|
|
231
|
+
detail,
|
|
232
|
+
dataset: {
|
|
233
|
+
...currentTarget.dataset,
|
|
234
|
+
...taroElement.dataset
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
},
|
|
238
|
+
funcName
|
|
239
|
+
);
|
|
240
|
+
}
|
|
241
|
+
} catch (error) {
|
|
242
|
+
ut.consoleText('Error: ' + error, 'error');
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
}
|
|
155
247
|
return result;
|
|
156
248
|
});
|
|
157
249
|
} else {
|
|
158
250
|
ut.consoleText('Taro3实例获取失败,请检查初始化逻辑!', 'warn');
|
|
159
251
|
eventHooks.nativeGrowing(['Page']);
|
|
160
252
|
}
|
|
253
|
+
};
|
|
161
254
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
255
|
+
// 保存vue3下使用setup写法的function component的导出方法名
|
|
256
|
+
proxyTaro3vue3 = () => {
|
|
257
|
+
const self = this;
|
|
258
|
+
this.taroVue.mixin({
|
|
259
|
+
beforeMount: function () {
|
|
260
|
+
// 存在tid说明是页面
|
|
261
|
+
if (this._?.props?.tid && !ut.isEmpty(this._.exposed)) {
|
|
262
|
+
const path = ut.head(ut.split(this._.props.tid, '?'));
|
|
263
|
+
const kvs = {};
|
|
264
|
+
ut.keys(this._.exposed).forEach((k) => {
|
|
265
|
+
if (this._.exposed[k].name) {
|
|
266
|
+
kvs[this._.exposed[k].name] = k;
|
|
267
|
+
}
|
|
268
|
+
});
|
|
269
|
+
self.exposedNames[path] = { ...kvs };
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
});
|
|
273
|
+
};
|
|
274
|
+
|
|
275
|
+
// taro3react获取方法名
|
|
276
|
+
taro3reactGetFuncName = (
|
|
277
|
+
originHandler: any,
|
|
278
|
+
taroEvent: any,
|
|
279
|
+
taroElement: any
|
|
280
|
+
) => {
|
|
281
|
+
const propsKey = ut
|
|
282
|
+
.keys(taroElement)
|
|
283
|
+
.find((key) => TARO_EVENT_PROPS_REG.test(key));
|
|
284
|
+
const propsHandler =
|
|
285
|
+
ut.niceTry(() => taroElement[propsKey][HANDLER[taroEvent.type]]) ??
|
|
286
|
+
originHandler.oldHandler ??
|
|
287
|
+
originHandler;
|
|
288
|
+
if (propsHandler?.value?.name) {
|
|
289
|
+
return propsHandler?.value?.name;
|
|
290
|
+
} else if (
|
|
291
|
+
propsHandler.name &&
|
|
292
|
+
!['handler', 'invoker'].includes(propsHandler.name)
|
|
293
|
+
) {
|
|
294
|
+
// class component匿名引用方法
|
|
295
|
+
let funcName = ut
|
|
296
|
+
.head(`${propsHandler}`.match(TARO_EVENT_REACT_FUNC1_REG))
|
|
297
|
+
?.replace('return ', '')
|
|
298
|
+
?.replace('(', '');
|
|
299
|
+
if (funcName) {
|
|
300
|
+
return ut.head(ut.drop(ut.split(funcName, '.'))) ?? propsHandler.name;
|
|
301
|
+
} else {
|
|
302
|
+
// component匿名引用方法
|
|
303
|
+
funcName = ut
|
|
304
|
+
.head(`${propsHandler}`.match(TARO_EVENT_REACT_FUNC2_REG))
|
|
305
|
+
?.replace('return ', '')
|
|
306
|
+
?.replace('(', '');
|
|
307
|
+
return funcName ?? propsHandler.name;
|
|
308
|
+
}
|
|
309
|
+
} else {
|
|
310
|
+
return this.getAnonymousFunc(taroElement);
|
|
311
|
+
}
|
|
312
|
+
};
|
|
313
|
+
|
|
314
|
+
// taro3vue3获取方法名
|
|
315
|
+
taro3vue3GetFuncName = (originHandler: any, taroElement: any) => {
|
|
316
|
+
if (ut.startsWith(`${originHandler.value}`.replace(' ', ''), 'function(')) {
|
|
317
|
+
// 使用emit监听组件的方法
|
|
318
|
+
let preFuncName = ut
|
|
319
|
+
.head(`${originHandler.value}`.match(TARO_EVENT_VUE_FUNC1_REG))
|
|
320
|
+
?.replace('return ', '');
|
|
321
|
+
try {
|
|
322
|
+
// 使用emit监听组件的方法要优先判断
|
|
323
|
+
if (preFuncName) {
|
|
324
|
+
// dev状态时是单引号
|
|
325
|
+
// eslint-disable-next-line
|
|
326
|
+
if (preFuncName.indexOf("'") > -1) {
|
|
327
|
+
// eslint-disable-next-line
|
|
328
|
+
preFuncName = ut.head(ut.drop(ut.split(preFuncName, "'")));
|
|
329
|
+
} else {
|
|
330
|
+
// build状态时是双引号
|
|
331
|
+
preFuncName = ut.head(ut.drop(ut.split(preFuncName, '"')));
|
|
332
|
+
}
|
|
333
|
+
} else {
|
|
334
|
+
// 普通引用方法/匿名引用方法/普通setup定义的方法
|
|
335
|
+
preFuncName = ut
|
|
336
|
+
.head(`${originHandler.value}`.match(TARO_EVENT_VUE_FUNC2_REG))
|
|
337
|
+
?.replace('return ', '');
|
|
338
|
+
// script setup定义且匿名引用的方法(需要配合defineExpose导出,否则是一个编译后的匿名单字母函数名)
|
|
339
|
+
if (!preFuncName) {
|
|
340
|
+
preFuncName = ut
|
|
341
|
+
.head(`${originHandler.value}`.match(TARO_EVENT_VUE_FUNC3_REG))
|
|
342
|
+
?.replace('return ', '');
|
|
343
|
+
}
|
|
344
|
+
// script setup定义普通引用的方法(需要配合defineExpose导出,否则是一个编译后的匿名单字母函数名)
|
|
345
|
+
if (!preFuncName) {
|
|
346
|
+
preFuncName = originHandler.value?.name;
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
} catch (error) {
|
|
350
|
+
preFuncName = '';
|
|
351
|
+
}
|
|
352
|
+
// 能获取到方法名
|
|
353
|
+
if (preFuncName) {
|
|
354
|
+
let funcName =
|
|
355
|
+
preFuncName.indexOf('.') > -1
|
|
356
|
+
? ut.head(ut.drop(ut.split(preFuncName, '.')))
|
|
357
|
+
: preFuncName;
|
|
358
|
+
let path = '';
|
|
359
|
+
if (taroElement?._root?.uid) {
|
|
360
|
+
path = ut.head(ut.split(taroElement._root.uid, '?'));
|
|
361
|
+
} else {
|
|
362
|
+
path = this.growingIO.dataStore.eventHooks.currentPage.path;
|
|
363
|
+
}
|
|
364
|
+
if (this.exposedNames[path]) {
|
|
365
|
+
funcName =
|
|
366
|
+
ut.niceTry(() => this.exposedNames[path][funcName]) ?? funcName;
|
|
367
|
+
}
|
|
368
|
+
return funcName;
|
|
369
|
+
} else {
|
|
370
|
+
// 不能获取方法名,直接构建一个匿名方法名
|
|
371
|
+
return this.getAnonymousFunc(taroElement);
|
|
372
|
+
}
|
|
373
|
+
} else if (originHandler?.value?.name) {
|
|
374
|
+
return originHandler.value.name;
|
|
375
|
+
} else {
|
|
376
|
+
return this.getAnonymousFunc(taroElement);
|
|
377
|
+
}
|
|
378
|
+
};
|
|
379
|
+
|
|
380
|
+
// 无法获取的方法名
|
|
381
|
+
getAnonymousFunc = (taroElement: any) => {
|
|
382
|
+
const { path } = this.growingIO.dataStore.eventHooks.currentPage;
|
|
383
|
+
const paths = path.split('/');
|
|
384
|
+
const idx = paths.findIndex((v) => v.indexOf('page') > -1) + 1;
|
|
385
|
+
const pageName = idx && paths[idx] ? paths[idx] : ut.last(paths);
|
|
386
|
+
return `${pageName}_Func${
|
|
387
|
+
ut.startsWith(taroElement.uid, '_')
|
|
388
|
+
? taroElement.uid
|
|
389
|
+
: '_' + taroElement.uid
|
|
390
|
+
}`;
|
|
192
391
|
};
|
|
193
392
|
|
|
194
393
|
// taro3使用vue2的代理
|
|
195
|
-
taro3Vue2Proxy = (
|
|
394
|
+
taro3Vue2Proxy = () => {
|
|
196
395
|
const self = this;
|
|
197
|
-
|
|
396
|
+
this.taroVue.mixin({
|
|
198
397
|
beforeMount: function () {
|
|
199
398
|
// 对传统methods写法的普通事件hook
|
|
200
399
|
const methods = this.$options.methods;
|
|
@@ -216,56 +415,6 @@ class GioTaroAdapter {
|
|
|
216
415
|
});
|
|
217
416
|
};
|
|
218
417
|
|
|
219
|
-
// taro3使用vue3的代理
|
|
220
|
-
taro3Vue3Proxy = (vue: any) => {
|
|
221
|
-
const { eventHooks } = this.growingIO.dataStore;
|
|
222
|
-
const self = this;
|
|
223
|
-
vue.mixin({
|
|
224
|
-
beforeMount: function () {
|
|
225
|
-
// hook逻辑
|
|
226
|
-
const transferMethods = (o) =>
|
|
227
|
-
ut.keys(o).forEach((k: string) => {
|
|
228
|
-
self.defineProperty(this, k, self.proxyMethods(k, this[k]));
|
|
229
|
-
});
|
|
230
|
-
// 对传统methods写法的普通事件hook
|
|
231
|
-
const methods = this.$options.methods;
|
|
232
|
-
if (methods) {
|
|
233
|
-
transferMethods(methods);
|
|
234
|
-
}
|
|
235
|
-
// 对setup中定义的事件hook
|
|
236
|
-
const setupState = this?._?.setupState;
|
|
237
|
-
if (setupState) {
|
|
238
|
-
transferMethods(setupState);
|
|
239
|
-
}
|
|
240
|
-
// 使用emit监听组件点击事件的处理
|
|
241
|
-
const tEmit = this._.emit;
|
|
242
|
-
this._.emit = function (...args) {
|
|
243
|
-
(() =>
|
|
244
|
-
eventHooks.customFcEffects(args[0], () => {}).apply(this, args))();
|
|
245
|
-
return tEmit.apply(this, args);
|
|
246
|
-
};
|
|
247
|
-
},
|
|
248
|
-
mounted() {
|
|
249
|
-
// this._.vnode.el要在mounted中才能获取到
|
|
250
|
-
// 对<script setup>写法的事件hook,编译时会匿名,需要配合expose
|
|
251
|
-
const exposed = this?._?.exposed ?? {};
|
|
252
|
-
self.exposedNames = {};
|
|
253
|
-
if (!ut.isEmpty(exposed)) {
|
|
254
|
-
const nExposed = {};
|
|
255
|
-
// 保存exposed供<script setup>写法的事件查找真实的事件名
|
|
256
|
-
ut.keys(exposed).forEach((k) => {
|
|
257
|
-
if (ut.isFunction(exposed[k])) {
|
|
258
|
-
self.exposedNames[exposed[k].name] = k;
|
|
259
|
-
nExposed[exposed[k].name] = exposed[k];
|
|
260
|
-
}
|
|
261
|
-
});
|
|
262
|
-
// 只能取到编译后的名称,需要从exposedNames中映射
|
|
263
|
-
self.traverseHook(this._.vnode.el, 0);
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
});
|
|
267
|
-
};
|
|
268
|
-
|
|
269
418
|
// 重写方法
|
|
270
419
|
proxyMethods = (name: string, method: any) => {
|
|
271
420
|
const { eventHooks } = this.growingIO.dataStore;
|
|
@@ -288,54 +437,6 @@ class GioTaroAdapter {
|
|
|
288
437
|
});
|
|
289
438
|
};
|
|
290
439
|
|
|
291
|
-
// 遍历hook节点方法
|
|
292
|
-
traverseHook = (node: any, i: number) => {
|
|
293
|
-
this.veiAutoEventHook(node, i);
|
|
294
|
-
if (node.childNodes && ut.isArray(node.childNodes)) {
|
|
295
|
-
node.childNodes.forEach((n, i) => {
|
|
296
|
-
this.traverseHook(n, i);
|
|
297
|
-
});
|
|
298
|
-
}
|
|
299
|
-
};
|
|
300
|
-
|
|
301
|
-
// vue3中查找并重写节点vei对象中的自定义事件
|
|
302
|
-
veiAutoEventHook = (node: any, i: number) => {
|
|
303
|
-
const { eventHooks } = this.growingIO.dataStore;
|
|
304
|
-
if (node._vei) {
|
|
305
|
-
ut.keys(node._vei).forEach((k) => {
|
|
306
|
-
if (eventHooks.actionEventTypes.includes(k)) {
|
|
307
|
-
const func = node._vei[k].value;
|
|
308
|
-
let funcName;
|
|
309
|
-
if (
|
|
310
|
-
(ut.startsWith(`${func}`, 'function ($event)') ||
|
|
311
|
-
ut.startsWith(`${func}`, 'function($event)')) &&
|
|
312
|
-
/return \$setup.[\w]+\(/.test(`${func}`)
|
|
313
|
-
) {
|
|
314
|
-
// 进入该判断说明客户对方法进行了传参,导致框架编译为匿名函数,此时需要我们处理一下拿到真实的方法名
|
|
315
|
-
const s = `${func}`.match(/return \$setup.[\w]+\(/)[0];
|
|
316
|
-
if (s) {
|
|
317
|
-
funcName = s.replace('return $setup.', '').replace('(', '');
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
// 没有获取到方法的情况下,通过exposedNames中存的值尝试匹配,不一定准,因为对象是无序的
|
|
321
|
-
if (!funcName) {
|
|
322
|
-
funcName = `${ut.keys(this.exposedNames)[i]}#${
|
|
323
|
-
Object.values(this.exposedNames)[i]
|
|
324
|
-
}`;
|
|
325
|
-
}
|
|
326
|
-
this.defineProperty(
|
|
327
|
-
node._vei[k],
|
|
328
|
-
'value',
|
|
329
|
-
this.proxyMethods(
|
|
330
|
-
this.exposedNames[func.name] || func.name || funcName,
|
|
331
|
-
func
|
|
332
|
-
)
|
|
333
|
-
);
|
|
334
|
-
}
|
|
335
|
-
});
|
|
336
|
-
}
|
|
337
|
-
};
|
|
338
|
-
|
|
339
440
|
// taro3中存储当前页面完整的数据以获取曝光事件中的dataset
|
|
340
441
|
// https://taro-docs.jd.com/taro/docs/react-overall#dataset
|
|
341
442
|
saveFullPage = (body: any) => {
|