@@ -15,6 +15,52 @@ const setRef = function (target, ref, isAsync) {
1515 }
1616 } )
1717}
18+ const proxyMethods = [ 'boundingClientRect' , 'scrollOffset' ]
19+ function rewriteAliCreateSelectorQuery ( target ) {
20+ const rawCreateSelectorQuery = target . createSelectorQuery
21+ target . createSelectorQuery = function ( ...args ) {
22+ let selectorQuery = rawCreateSelectorQuery . apply ( target , args )
23+ const cbs = [ ]
24+
25+ if ( typeof selectorQuery === 'undefined' ) {
26+ // 兜底 selectorQuery 在ali为 undefined 情况
27+ // 调用 createSelectorQuery时,组件实例已经被销毁,ali this._originCreateSelectorQuery 返回 undefined。导致后续 selectorQuery[name] 报错
28+ // 方案:对齐微信,微信实例销毁时,其他调用正常,仅 createSelectorQuery.exec 不执行回调
29+ // 复现:setTimeout 中调用,倒计时未回调时切换页面
30+ selectorQuery = { }
31+ // ['boundingClientRect', 'context', 'exec', 'fields', 'in', 'node', 'scrollOffset', 'select', 'selectAll', 'selectViewport', 'toImage']
32+ const backupMethodKeys = Object . keys ( envObj . createSelectorQuery ( ) )
33+ const backupFn = function ( ) {
34+ return selectorQuery
35+ }
36+ backupMethodKeys . forEach ( key => {
37+ selectorQuery [ key ] = backupFn
38+ } )
39+ return selectorQuery
40+ }
41+
42+ proxyMethods . forEach ( ( name ) => {
43+ const originalMethod = selectorQuery [ name ]
44+ selectorQuery [ name ] = function ( cb = noop ) {
45+ cbs . push ( cb )
46+ return originalMethod . call ( this )
47+ }
48+ } )
49+
50+ const originalExec = selectorQuery . exec
51+ selectorQuery . exec = function ( originalCb = noop ) {
52+ const cb = function ( results ) {
53+ results . forEach ( ( item , index ) => {
54+ cbs [ index ] && cbs [ index ] ( item )
55+ } )
56+ originalCb ( results )
57+ }
58+ return originalExec . call ( this , cb )
59+ }
60+
61+ return selectorQuery
62+ }
63+ }
1864
1965export default function getRefsMixin ( ) {
2066 const refsMixin = {
@@ -24,8 +70,7 @@ export default function getRefsMixin () {
2470 this . __getRefs ( )
2571
2672 if ( __mpx_mode__ === 'ali' ) {
27- this . _originCreateSelectorQuery = this . createSelectorQuery
28- this . createSelectorQuery = this . _createSelectorQuery
73+ rewriteAliCreateSelectorQuery ( this )
2974 }
3075 } ,
3176 methods : {
@@ -68,51 +113,7 @@ export default function getRefsMixin () {
68113 }
69114 } )
70115
71- const proxyMethods = [ 'boundingClientRect' , 'scrollOffset' ]
72-
73116 Object . assign ( refsMixin . methods , {
74- _createSelectorQuery ( ...args ) {
75- let selectorQuery = this . _originCreateSelectorQuery ( ...args )
76- const cbs = [ ]
77-
78- if ( typeof selectorQuery === 'undefined' ) {
79- // 兜底 selectorQuery 在ali为 undefined 情况
80- // 调用 createSelectorQuery时,组件实例已经被销毁,ali this._originCreateSelectorQuery 返回 undefined。导致后续 selectorQuery[name] 报错
81- // 方案:对齐微信,微信实例销毁时,其他调用正常,仅 createSelectorQuery.exec 不执行回调
82- // 复现:setTimeout 中调用,倒计时未回调时切换页面
83- selectorQuery = { }
84- // ['boundingClientRect', 'context', 'exec', 'fields', 'in', 'node', 'scrollOffset', 'select', 'selectAll', 'selectViewport', 'toImage']
85- const backupMethodKeys = Object . keys ( envObj . createSelectorQuery ( ) )
86- const backupFn = function ( ) {
87- return selectorQuery
88- }
89- backupMethodKeys . forEach ( key => {
90- selectorQuery [ key ] = backupFn
91- } )
92- return selectorQuery
93- }
94-
95- proxyMethods . forEach ( ( name ) => {
96- const originalMethod = selectorQuery [ name ]
97- selectorQuery [ name ] = function ( cb = noop ) {
98- cbs . push ( cb )
99- return originalMethod . call ( this )
100- }
101- } )
102-
103- const originalExec = selectorQuery . exec
104- selectorQuery . exec = function ( originalCb = noop ) {
105- const cb = function ( results ) {
106- results . forEach ( ( item , index ) => {
107- cbs [ index ] && cbs [ index ] ( item )
108- } )
109- originalCb ( results )
110- }
111- return originalExec . call ( this , cb )
112- }
113-
114- return selectorQuery
115- } ,
116117 selectComponent ( selector ) {
117118 return this . $selectComponent ( selector )
118119 } ,
0 commit comments