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.
@@ -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
- subpackage: { type: 'boolean', default: false },
32
+ // 请求超时时长
33
+ requestTimeout: { type: 'number', default: 5000 },
34
34
  // taro框架实例
35
35
  taro: { type: ['object', 'module'], default: false },
36
36
  // taro框架vue实例
@@ -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,
@@ -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);
@@ -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: this.requestTimeout,
166
+ timeout: vdsConfig.requestTimeout,
172
167
  fail: (result: any) => {
173
168
  if (![200, 204].includes(result.code)) {
174
169
  if (isArray(eventsQueue)) {
@@ -2,7 +2,6 @@
2
2
  * 名称:淘宝小程序单发插件
3
3
  * 用途:用于提供淘宝小程序云函数和云应用的请求方法。
4
4
  */
5
- import { Event } from '@@/types/base';
6
5
  import { GrowingIOType } from '@@/types/growingIO';
7
6
 
8
7
  let ut;
@@ -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 vue: any;
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, vdsConfig, emitter, minipInstance, gioPlatform } =
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 (event === 'Page onReadyEnd') {
24
- if (this.taro && ut.isTaro3(this.taro)) {
38
+ if (['Page onShow', 'Page onReady'].includes(event)) {
39
+ if (this.taro && this.taroVersion === '3') {
25
40
  // 提前存储页面节点信息用来获取dataset
26
- this.growingIO.plugins?.gioTaroAdapter?.saveFullPage(document.body);
41
+ this.saveFullPage(document.body);
27
42
  // taro3开发时要等onready才能取到节点,所以补充做一次曝光监听
28
- if (!['swan', 'tt'].includes(gioPlatform)) {
29
- setTimeout(
30
- () =>
31
- minipInstance.initImpression(minipInstance.getCurrentPage()),
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
- if (!this.taro) {
44
- this.taro = this.growingIO?.vdsConfig?.taro;
45
- }
46
- if (!this.vue) {
47
- this.vue = this.growingIO?.vdsConfig?.taroVue;
48
- }
49
- const { Current, createComponent } = this.taro;
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
- } else if (Current && !createComponent) {
53
- this.proxyTaro3(this.taro, this.vue);
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 = (taro: any, vue?: any) => {
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 { eventHooks } = this.growingIO.dataStore;
137
- // 重写页面生命周期
138
- const originCall = taroRuntime?.hooks?.call;
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(taroRuntime.hooks, 'call', function (...args) {
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
- ut.keys(pageObject).forEach((k) => {
146
- if (eventHooks.pageHandlers.includes(k)) {
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
- const proxyAddEventListener = (addEventListener) => {
164
- return function (...args) {
165
- const originHandler = args[1];
166
- const handler = self.growingIO.dataStore.eventHooks.customFcEffects(
167
- originHandler.name,
168
- originHandler
169
- );
170
- self.taro3Listeners[originHandler.name] = handler;
171
- return addEventListener.apply(this, [args[0], handler, args[2]]);
172
- };
173
- };
174
- const proxyRemoveEventListener = (removeEventListener) => {
175
- return function (...args) {
176
- return removeEventListener.apply(this, [
177
- args[0],
178
- self.taro3Listeners[args[1].name]
179
- ]);
180
- };
181
- };
182
- self.defineProperty(
183
- taroNode,
184
- 'addEventListener',
185
- proxyAddEventListener(taroNode.addEventListener)
186
- );
187
- self.defineProperty(
188
- taroNode,
189
- 'removeEventListener',
190
- proxyRemoveEventListener(taroNode.removeEventListener)
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 = (vue: any) => {
394
+ taro3Vue2Proxy = () => {
196
395
  const self = this;
197
- vue.mixin({
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) => {