@mpxjs/webpack-plugin 2.10.6-beta.2 → 2.10.6-beta.4

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.
Files changed (46) hide show
  1. package/lib/file-loader.js +1 -1
  2. package/lib/index.js +35 -14
  3. package/lib/platform/index.js +2 -4
  4. package/lib/platform/json/wx/index.js +43 -25
  5. package/lib/platform/template/wx/component-config/fix-component-name.js +2 -2
  6. package/lib/platform/template/wx/component-config/index.js +2 -2
  7. package/lib/platform/template/wx/component-config/template.js +1 -26
  8. package/lib/platform/template/wx/index.js +5 -11
  9. package/lib/react/LoadAsyncChunkModule.js +68 -0
  10. package/lib/react/index.js +3 -1
  11. package/lib/react/processJSON.js +72 -17
  12. package/lib/react/processScript.js +4 -3
  13. package/lib/react/script-helper.js +92 -18
  14. package/lib/runtime/components/react/AsyncContainer.tsx +217 -0
  15. package/lib/runtime/components/react/AsyncSuspense.tsx +81 -0
  16. package/lib/runtime/components/react/dist/AsyncContainer.jsx +160 -0
  17. package/lib/runtime/components/react/dist/AsyncSuspense.jsx +68 -0
  18. package/lib/runtime/components/react/dist/getInnerListeners.js +1 -1
  19. package/lib/runtime/components/react/dist/mpx-input.jsx +1 -1
  20. package/lib/runtime/components/react/dist/mpx-movable-view.jsx +2 -2
  21. package/lib/runtime/components/react/dist/mpx-swiper-item.jsx +2 -2
  22. package/lib/runtime/components/react/dist/mpx-swiper.jsx +53 -27
  23. package/lib/runtime/components/react/dist/mpx-web-view.jsx +14 -28
  24. package/lib/runtime/components/react/dist/useAnimationHooks.js +2 -87
  25. package/lib/runtime/components/react/dist/utils.jsx +84 -0
  26. package/lib/runtime/components/react/getInnerListeners.ts +1 -1
  27. package/lib/runtime/components/react/mpx-input.tsx +1 -1
  28. package/lib/runtime/components/react/mpx-movable-view.tsx +2 -2
  29. package/lib/runtime/components/react/mpx-swiper-item.tsx +2 -2
  30. package/lib/runtime/components/react/mpx-swiper.tsx +53 -25
  31. package/lib/runtime/components/react/mpx-web-view.tsx +13 -33
  32. package/lib/runtime/components/react/types/global.d.ts +15 -0
  33. package/lib/runtime/components/react/useAnimationHooks.ts +2 -85
  34. package/lib/runtime/components/react/utils.tsx +83 -1
  35. package/lib/runtime/optionProcessor.js +2 -2
  36. package/lib/template-compiler/compiler.js +11 -61
  37. package/lib/utils/dom-tag-config.js +17 -3
  38. package/lib/web/index.js +0 -2
  39. package/lib/web/processScript.js +7 -29
  40. package/lib/web/processTemplate.js +4 -10
  41. package/lib/web/script-helper.js +1 -1
  42. package/package.json +1 -1
  43. package/lib/dependencies/WriteVfsDependency.js +0 -46
  44. package/lib/utils/get-template-content.js +0 -47
  45. package/lib/web/template2vue.js +0 -280
  46. package/lib/web/wxml-template-loader.js +0 -29
@@ -23,6 +23,7 @@ import Portal from './mpx-portal'
23
23
  * ✔ easing-function ="easeOutCubic"
24
24
  * ✘ display-multiple-items
25
25
  * ✘ snap-to-edge
26
+ * ✔ disableGesture
26
27
  */
27
28
  type EaseType = 'default' | 'linear' | 'easeInCubic' | 'easeOutCubic' | 'easeInOutCubic'
28
29
  type StrAbsoType = 'absoluteX' | 'absoluteY'
@@ -206,6 +207,10 @@ const SwiperWrapper = forwardRef<HandlerRef<View, SwiperProps>, SwiperProps>((pr
206
207
  const moveTranstion = useSharedValue(0)
207
208
  // 记录从onBegin 到 onTouchesUp 的时间
208
209
  const moveTime = useSharedValue(0)
210
+ // 记录从onBegin 到 onTouchesCancelled 另外一个方向移动的距离
211
+ const anotherDirectionMove = useSharedValue(0)
212
+ // 另一个方向的
213
+ const anotherAbso = 'absolute' + (dir === 'x' ? 'y' : 'x').toUpperCase() as StrAbsoType
209
214
  const timerId = useRef(0 as number | ReturnType<typeof setTimeout>)
210
215
  const intervalTimer = props.interval || 500
211
216
 
@@ -504,7 +509,11 @@ const SwiperWrapper = forwardRef<HandlerRef<View, SwiperProps>, SwiperProps>((pr
504
509
  }, [children.length])
505
510
 
506
511
  useEffect(() => {
507
- updateCurrent(props.current || 0, step.value)
512
+ // 1. 如果用户在touch的过程中, 外部更新了current以外部为准(小程序表现)
513
+ // 2. 手指滑动过程中更新索引,外部会把current再穿进来,导致offset直接更新了
514
+ if (props.current !== currentIndex.value) {
515
+ updateCurrent(props.current || 0, step.value)
516
+ }
508
517
  }, [props.current])
509
518
 
510
519
  useEffect(() => {
@@ -566,18 +575,25 @@ const SwiperWrapper = forwardRef<HandlerRef<View, SwiperProps>, SwiperProps>((pr
566
575
  targetOffset: -moveToTargetPos
567
576
  }
568
577
  }
569
- function canMove (eventData: EventDataType) {
578
+ function checkUnCircular (eventData: EventDataType) {
570
579
  'worklet'
571
580
  const { translation } = eventData
572
581
  const currentOffset = Math.abs(offset.value)
573
- if (!circularShared.value) {
574
- if (translation < 0) {
575
- return currentOffset < step.value * (childrenLength.value - 1)
576
- } else {
577
- return currentOffset > 0
582
+ // 向右滑动swiper
583
+ if (translation < 0) {
584
+ const boundaryOffset = step.value * (childrenLength.value - 1)
585
+ const gestureMovePos = Math.abs(translation) + currentOffset
586
+ return {
587
+ // 防止快速连续向右滑动时,手势移动的距离 加 当前的offset超出边界
588
+ targetOffset: gestureMovePos > boundaryOffset ? -boundaryOffset : offset.value + translation,
589
+ canMove: currentOffset < boundaryOffset
578
590
  }
579
591
  } else {
580
- return true
592
+ const gestureMovePos = currentOffset - translation
593
+ return {
594
+ targetOffset: gestureMovePos < 0 ? 0 : offset.value + translation,
595
+ canMove: currentOffset > 0
596
+ }
581
597
  }
582
598
  }
583
599
  function handleEnd (eventData: EventDataType) {
@@ -636,7 +652,7 @@ const SwiperWrapper = forwardRef<HandlerRef<View, SwiperProps>, SwiperProps>((pr
636
652
  }
637
653
  })
638
654
  }
639
- function handleLongPress () {
655
+ function computeHalf () {
640
656
  'worklet'
641
657
  const currentOffset = Math.abs(offset.value)
642
658
  let preOffset = (currentIndex.value + patchElmNumShared.value) * step.value
@@ -646,6 +662,14 @@ const SwiperWrapper = forwardRef<HandlerRef<View, SwiperProps>, SwiperProps>((pr
646
662
  // 正常事件中拿到的transition值(正向滑动<0,倒着滑>0)
647
663
  const diffOffset = preOffset - currentOffset
648
664
  const half = Math.abs(diffOffset) > step.value / 2
665
+ return {
666
+ diffOffset,
667
+ half
668
+ }
669
+ }
670
+ function handleLongPress () {
671
+ 'worklet'
672
+ const { diffOffset, half } = computeHalf()
649
673
  if (+diffOffset === 0) {
650
674
  runOnJS(resumeLoop)()
651
675
  } else if (half) {
@@ -701,18 +725,29 @@ const SwiperWrapper = forwardRef<HandlerRef<View, SwiperProps>, SwiperProps>((pr
701
725
  runOnJS(pauseLoop)()
702
726
  preAbsolutePos.value = e[strAbso]
703
727
  moveTranstion.value = e[strAbso]
728
+ anotherDirectionMove.value = e[anotherAbso]
704
729
  moveTime.value = new Date().getTime()
705
730
  })
706
- .onTouchesMove((e) => {
731
+ .onUpdate((e) => {
707
732
  'worklet'
708
733
  if (touchfinish.value) return
709
- const touchEventData = e.changedTouches[0]
710
- const moveDistance = touchEventData[strAbso] - preAbsolutePos.value
734
+ const moveDistance = e[strAbso] - preAbsolutePos.value
711
735
  const eventData = {
712
736
  translation: moveDistance
713
737
  }
714
- // 处理用户一直拖拽到临界点的场景, 不会执行onEnd
715
- if (!circularShared.value && !canMove(eventData)) {
738
+ // 1. 在Move过程中,如果手指一直没抬起来,超过一半的话也会更新索引
739
+ const { half } = computeHalf()
740
+ if (half) {
741
+ const { selectedIndex } = getTargetPosition(eventData)
742
+ currentIndex.value = selectedIndex
743
+ }
744
+ // 2. 处理用户一直拖拽到临界点的场景, 不会执行onEnd
745
+ const { canMove, targetOffset } = checkUnCircular(eventData)
746
+ if (!circularShared.value) {
747
+ if (canMove) {
748
+ offset.value = targetOffset
749
+ preAbsolutePos.value = e[strAbso]
750
+ }
716
751
  return
717
752
  }
718
753
  const { isBoundary, resetOffset } = reachBoundary(eventData)
@@ -721,28 +756,21 @@ const SwiperWrapper = forwardRef<HandlerRef<View, SwiperProps>, SwiperProps>((pr
721
756
  } else {
722
757
  offset.value = moveDistance + offset.value
723
758
  }
724
- preAbsolutePos.value = touchEventData[strAbso]
759
+ preAbsolutePos.value = e[strAbso]
725
760
  })
726
- .onTouchesUp((e) => {
761
+ .onFinalize((e) => {
727
762
  'worklet'
728
763
  if (touchfinish.value) return
729
- const touchEventData = e.changedTouches[0]
730
- const moveDistance = touchEventData[strAbso] - moveTranstion.value
764
+ const moveDistance = e[strAbso] - moveTranstion.value
731
765
  touchfinish.value = true
732
766
  const eventData = {
733
767
  translation: moveDistance
734
768
  }
735
- if (childrenLength.value === 1) {
736
- return handleBackInit()
737
- }
738
- // 用户手指按下起来, 需要计算正确的位置, 比如在滑动过程中突然按下然后起来,需要计算到正确的位置
739
- if (!circularShared.value && !canMove(eventData)) {
740
- return
741
- }
742
769
  const strVelocity = moveDistance / (new Date().getTime() - moveTime.value) * 1000
743
770
  if (Math.abs(strVelocity) < longPressRatio) {
744
771
  handleLongPress()
745
772
  } else {
773
+ // 如果触发了onTouchesCancelled,不会触发onUpdate不会更新offset值, 索引不会变更
746
774
  handleEnd(eventData)
747
775
  }
748
776
  })
@@ -1,6 +1,7 @@
1
- import { forwardRef, useRef, useContext, useMemo, useState, useCallback, useEffect } from 'react'
1
+ import { forwardRef, useRef, useContext, useMemo, useState } from 'react'
2
2
  import { warn, isFunction } from '@mpxjs/utils'
3
3
  import Portal from './mpx-portal/index'
4
+ import { usePreventRemove, PreventRemoveEvent } from '@react-navigation/native'
4
5
  import { getCustomEvent } from './getInnerListeners'
5
6
  import { promisify, redirectTo, navigateTo, navigateBack, reLaunch, switchTab } from '@mpxjs/api-proxy'
6
7
  import { WebView } from 'react-native-webview'
@@ -75,7 +76,6 @@ const styles = StyleSheet.create({
75
76
  borderRadius: 10
76
77
  }
77
78
  })
78
-
79
79
  const _WebView = forwardRef<HandlerRef<WebView, WebViewProps>, WebViewProps>((props, ref): JSX.Element | null => {
80
80
  const { src, bindmessage, bindload, binderror } = props
81
81
  const mpx = global.__mpx
@@ -100,8 +100,8 @@ const _WebView = forwardRef<HandlerRef<WebView, WebViewProps>, WebViewProps>((pr
100
100
  const webViewRef = useRef<WebView>(null)
101
101
  const fristLoaded = useRef<boolean>(false)
102
102
  const isLoadError = useRef<boolean>(false)
103
+ const isNavigateBack = useRef<boolean>(false)
103
104
  const statusCode = useRef<string|number>('')
104
- const [isLoaded, setIsLoaded] = useState<boolean>(true)
105
105
  const defaultWebViewStyle = {
106
106
  position: 'absolute' as const,
107
107
  left: 0,
@@ -109,30 +109,18 @@ const _WebView = forwardRef<HandlerRef<WebView, WebViewProps>, WebViewProps>((pr
109
109
  top: 0,
110
110
  bottom: 0
111
111
  }
112
- const canGoBack = useRef<boolean>(false)
113
- const isNavigateBack = useRef<boolean>(false)
114
112
 
115
- const beforeRemoveHandle = (e: Event) => {
116
- if (canGoBack.current && !isNavigateBack.current) {
113
+ const navigation = useNavigation()
114
+ const [isIntercept, setIsIntercept] = useState<boolean>(false)
115
+ usePreventRemove(isIntercept, (event: PreventRemoveEvent) => {
116
+ const { data } = event
117
+ if (isNavigateBack.current) {
118
+ navigation?.dispatch(data.action)
119
+ } else {
117
120
  webViewRef.current?.goBack()
118
- e.preventDefault()
119
121
  }
120
122
  isNavigateBack.current = false
121
- }
122
-
123
- const navigation = useNavigation()
124
-
125
- // useEffect(() => {
126
- // let beforeRemoveSubscription:any
127
- // if (__mpx_mode__ !== 'ios') {
128
- // beforeRemoveSubscription = navigation?.addListener?.('beforeRemove', beforeRemoveHandle)
129
- // }
130
- // return () => {
131
- // if (isFunction(beforeRemoveSubscription)) {
132
- // beforeRemoveSubscription()
133
- // }
134
- // }
135
- // }, [])
123
+ })
136
124
 
137
125
  useNodesRef<WebView, WebViewProps>(props, ref, webViewRef, {
138
126
  style: defaultWebViewStyle
@@ -183,14 +171,14 @@ const _WebView = forwardRef<HandlerRef<WebView, WebViewProps>, WebViewProps>((pr
183
171
  }
184
172
  const _changeUrl = function (navState: WebViewNavigation) {
185
173
  if (navState.navigationType) { // navigationType这个事件在页面开始加载时和页面加载完成时都会被触发所以判断这个避免其他无效触发执行该逻辑
186
- canGoBack.current = navState.canGoBack
187
174
  currentPage.__webViewUrl = navState.url
175
+ setIsIntercept(navState.canGoBack)
188
176
  }
189
177
  }
190
178
 
191
179
  const _onLoadProgress = function (event: WebViewProgressEvent) {
192
180
  if (__mpx_mode__ !== 'ios') {
193
- canGoBack.current = event.nativeEvent.canGoBack
181
+ setIsIntercept(event.nativeEvent.canGoBack)
194
182
  }
195
183
  }
196
184
  const _message = function (res: WebViewMessageEvent) {
@@ -279,7 +267,6 @@ const _WebView = forwardRef<HandlerRef<WebView, WebViewProps>, WebViewProps>((pr
279
267
  }
280
268
  const onLoadEndHandle = function (res: WebViewEvent) {
281
269
  fristLoaded.current = true
282
- setIsLoaded(true)
283
270
  const src = res.nativeEvent?.url
284
271
  if (isLoadError.current) {
285
272
  isLoadError.current = false
@@ -325,11 +312,6 @@ const _WebView = forwardRef<HandlerRef<WebView, WebViewProps>, WebViewProps>((pr
325
312
  setPageLoadErr(true)
326
313
  }
327
314
  }
328
- const onLoadStart = function () {
329
- if (!fristLoaded.current) {
330
- setIsLoaded(false)
331
- }
332
- }
333
315
 
334
316
  return (
335
317
  <Portal>
@@ -342,7 +324,6 @@ const _WebView = forwardRef<HandlerRef<WebView, WebViewProps>, WebViewProps>((pr
342
324
  )
343
325
  : (<WebView
344
326
  style={ defaultWebViewStyle }
345
- pointerEvents={ isLoaded ? 'auto' : 'none' }
346
327
  source={{ uri: src }}
347
328
  ref={webViewRef}
348
329
  javaScriptEnabled={true}
@@ -353,7 +334,6 @@ const _WebView = forwardRef<HandlerRef<WebView, WebViewProps>, WebViewProps>((pr
353
334
  onLoadEnd={onLoadEnd}
354
335
  onHttpError={onHttpError}
355
336
  onError={onError}
356
- onLoadStart={onLoadStart}
357
337
  allowsBackForwardNavigationGestures={true}
358
338
  ></WebView>)}
359
339
  </Portal>
@@ -42,6 +42,21 @@ declare let global: {
42
42
 
43
43
  declare module '@react-navigation/native' {
44
44
  export function useNavigation (): Record<string, any>
45
+ export function usePreventRemove(
46
+ enabled: boolean,
47
+ callback: (e: { data: { action: any } }) => void
48
+ ): void;
49
+ export interface PreventRemoveEvent {
50
+ data: {
51
+ action: NavigationAction;
52
+ route: {
53
+ key: string;
54
+ name: string;
55
+ params?: unknown;
56
+ };
57
+ };
58
+ preventDefault(): void;
59
+ }
45
60
  }
46
61
 
47
62
  declare module '*.png'
@@ -84,88 +84,6 @@ const InitialValue: ExtendedViewStyle = Object.assign({
84
84
  const TransformOrigin = 'transformOrigin'
85
85
  // transform
86
86
  const isTransform = (key: string) => Object.keys(TransformInitial).includes(key)
87
- // 多value解析
88
- const parseValues = (str: string, char = ' ') => {
89
- let stack = 0
90
- let temp = ''
91
- const result = []
92
- for (let i = 0; i < str.length; i++) {
93
- if (str[i] === '(') {
94
- stack++
95
- } else if (str[i] === ')') {
96
- stack--
97
- }
98
- // 非括号内 或者 非分隔字符且非空
99
- if (stack !== 0 || (str[i] !== char && str[i] !== ' ')) {
100
- temp += str[i]
101
- }
102
- if ((stack === 0 && str[i] === char) || i === str.length - 1) {
103
- result.push(temp)
104
- temp = ''
105
- }
106
- }
107
- return result
108
- }
109
- // parse string transform, eg: transform: 'rotateX(45deg) rotateZ(0.785398rad)'
110
- const parseTransform = (transformStr: string) => {
111
- const values = parseValues(transformStr)
112
- const transform: {[propName: string]: string|number|number[]}[] = []
113
- values.forEach(item => {
114
- const match = item.match(/([/\w]+)\((.+)\)/)
115
- if (match && match.length >= 3) {
116
- let key = match[1]
117
- const val = match[2]
118
- switch (key) {
119
- case 'translateX':
120
- case 'translateY':
121
- case 'scaleX':
122
- case 'scaleY':
123
- case 'rotateX':
124
- case 'rotateY':
125
- case 'rotateZ':
126
- case 'rotate':
127
- case 'skewX':
128
- case 'skewY':
129
- case 'perspective':
130
- // rotate 处理成 rotateZ
131
- key = key === 'rotate' ? 'rotateZ' : key
132
- // 单个值处理
133
- transform.push({ [key]: global.__formatValue(val) })
134
- break
135
- case 'matrix':
136
- transform.push({ [key]: parseValues(val, ',').map(val => +val) })
137
- break
138
- case 'translate':
139
- case 'scale':
140
- case 'skew':
141
- case 'translate3d': // x y 支持 z不支持
142
- case 'scale3d': // x y 支持 z不支持
143
- {
144
- // 2 个以上的值处理
145
- key = key.replace('3d', '')
146
- const vals = parseValues(val, ',').splice(0, 3)
147
- // scale(.5) === scaleX(.5) scaleY(.5)
148
- if (vals.length === 1 && key === 'scale') {
149
- vals.push(vals[0])
150
- }
151
- const xyz = ['X', 'Y', 'Z']
152
- transform.push(...vals.map((v, index) => {
153
- return { [`${key}${xyz[index] || ''}`]: global.__formatValue(v.trim()) }
154
- }))
155
- break
156
- }
157
- }
158
- }
159
- })
160
- return transform
161
- }
162
- // format style
163
- const formatStyle = (style: ExtendedViewStyle): ExtendedViewStyle => {
164
- if (!style.transform || Array.isArray(style.transform)) return style
165
- return Object.assign({}, style, {
166
- transform: parseTransform(style.transform)
167
- })
168
- }
169
87
 
170
88
  // transform 数组转对象
171
89
  function getTransformObj (transforms: { [propName: string]: string | number }[]) {
@@ -176,7 +94,7 @@ function getTransformObj (transforms: { [propName: string]: string | number }[])
176
94
  }
177
95
 
178
96
  export default function useAnimationHooks<T, P> (props: _ViewProps & { enableAnimation?: boolean, layoutRef: MutableRefObject<any>, transitionend?: (event: NativeSyntheticEvent<TouchEvent> | unknown) => void }) {
179
- const { style = {}, animation, enableAnimation, transitionend, layoutRef } = props
97
+ const { style: originalStyle = {}, animation, enableAnimation, transitionend, layoutRef } = props
180
98
  const enableStyleAnimation = enableAnimation || !!animation
181
99
  const enableAnimationRef = useRef(enableStyleAnimation)
182
100
  if (enableAnimationRef.current !== enableStyleAnimation) {
@@ -185,7 +103,6 @@ export default function useAnimationHooks<T, P> (props: _ViewProps & { enableAni
185
103
 
186
104
  if (!enableAnimationRef.current) return { enableStyleAnimation: false }
187
105
 
188
- const originalStyle = formatStyle(style)
189
106
  // id 标识
190
107
  const id = animation?.id || -1
191
108
  // 有动画样式的 style key
@@ -214,7 +131,7 @@ export default function useAnimationHooks<T, P> (props: _ViewProps & { enableAni
214
131
  useEffect(() => {
215
132
  // style 更新后同步更新 lastStyleRef & shareValMap
216
133
  updateStyleVal()
217
- }, [style])
134
+ }, [originalStyle])
218
135
  // ** 获取动画样式prop & 驱动动画
219
136
  // eslint-disable-next-line react-hooks/rules-of-hooks
220
137
  useEffect(() => {
@@ -285,7 +285,86 @@ function transformPosition (styleObj: Record<string, any>, meta: PositionMeta) {
285
285
  meta.hasPositionFixed = true
286
286
  }
287
287
  }
288
-
288
+ // 多value解析
289
+ function parseValues (str: string, char = ' ') {
290
+ let stack = 0
291
+ let temp = ''
292
+ const result = []
293
+ for (let i = 0; i < str.length; i++) {
294
+ if (str[i] === '(') {
295
+ stack++
296
+ } else if (str[i] === ')') {
297
+ stack--
298
+ }
299
+ // 非括号内 或者 非分隔字符且非空
300
+ if (stack !== 0 || (str[i] !== char && str[i] !== ' ')) {
301
+ temp += str[i]
302
+ }
303
+ if ((stack === 0 && str[i] === char) || i === str.length - 1) {
304
+ result.push(temp)
305
+ temp = ''
306
+ }
307
+ }
308
+ return result
309
+ }
310
+ // parse string transform, eg: transform: 'rotateX(45deg) rotateZ(0.785398rad)'
311
+ function parseTransform (transformStr: string) {
312
+ const values = parseValues(transformStr)
313
+ const transform: {[propName: string]: string|number|number[]}[] = []
314
+ values.forEach(item => {
315
+ const match = item.match(/([/\w]+)\((.+)\)/)
316
+ if (match && match.length >= 3) {
317
+ let key = match[1]
318
+ const val = match[2]
319
+ switch (key) {
320
+ case 'translateX':
321
+ case 'translateY':
322
+ case 'scaleX':
323
+ case 'scaleY':
324
+ case 'rotateX':
325
+ case 'rotateY':
326
+ case 'rotateZ':
327
+ case 'rotate':
328
+ case 'skewX':
329
+ case 'skewY':
330
+ case 'perspective':
331
+ // rotate 处理成 rotateZ
332
+ key = key === 'rotate' ? 'rotateZ' : key
333
+ // 单个值处理
334
+ transform.push({ [key]: global.__formatValue(val) })
335
+ break
336
+ case 'matrix':
337
+ transform.push({ [key]: parseValues(val, ',').map(val => +val) })
338
+ break
339
+ case 'translate':
340
+ case 'scale':
341
+ case 'skew':
342
+ case 'translate3d': // x y 支持 z不支持
343
+ case 'scale3d': // x y 支持 z不支持
344
+ {
345
+ // 2 个以上的值处理
346
+ key = key.replace('3d', '')
347
+ const vals = parseValues(val, ',').splice(0, 3)
348
+ // scale(.5) === scaleX(.5) scaleY(.5)
349
+ if (vals.length === 1 && key === 'scale') {
350
+ vals.push(vals[0])
351
+ }
352
+ const xyz = ['X', 'Y', 'Z']
353
+ transform.push(...vals.map((v, index) => {
354
+ return { [`${key}${xyz[index] || ''}`]: global.__formatValue(v.trim()) }
355
+ }))
356
+ break
357
+ }
358
+ }
359
+ }
360
+ })
361
+ return transform
362
+ }
363
+ // format style transform
364
+ function transformTransform (style: Record<string, any>) {
365
+ if (!style.transform || Array.isArray(style.transform)) return
366
+ style.transform = parseTransform(style.transform)
367
+ }
289
368
  interface TransformStyleConfig {
290
369
  enableVar?: boolean
291
370
  externalVarContext?: Record<string, any>
@@ -428,6 +507,9 @@ export function useTransformStyle (styleObj: Record<string, any> = {}, { enableV
428
507
  // transform number enum stringify
429
508
  transformStringify(normalStyle)
430
509
 
510
+ // transform 字符串格式转化数组格式
511
+ transformTransform(normalStyle)
512
+
431
513
  return {
432
514
  hasVarDec,
433
515
  varContextRef,
@@ -79,7 +79,7 @@ registered in parent context!`)
79
79
  transitionName: ''
80
80
  }
81
81
  }
82
- if (!global.__mpx.config.webConfig?.disablePageTransition) {
82
+ if (!global.__mpx.config.webConfig.disablePageTransition) {
83
83
  option.watch = {
84
84
  $route: {
85
85
  handler () {
@@ -161,7 +161,7 @@ function createApp ({ componentsMap, Vue, pagesMap, firstPage, VueRouter, App, t
161
161
  redirect: '/' + firstPage
162
162
  })
163
163
  }
164
- const webRouteConfig = global.__mpx.config.webConfig?.routeConfig || global.__mpx.config.webRouteConfig
164
+ const webRouteConfig = global.__mpx.config.webConfig.routeConfig || global.__mpx.config.webRouteConfig
165
165
  global.__mpxRouter = option.router = new VueRouter(extend({ routes }, webRouteConfig))
166
166
  let mpxStackPath = []
167
167
  if (isBrowser) {