@mpxjs/core 2.9.67 → 2.9.69-beta.0

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 (40) hide show
  1. package/package.json +19 -7
  2. package/src/convertor/convertor.js +11 -32
  3. package/src/convertor/wxToAli.js +3 -3
  4. package/src/convertor/wxToReact.js +1 -1
  5. package/src/convertor/wxToSwan.js +3 -3
  6. package/src/convertor/wxToWeb.js +3 -3
  7. package/src/core/proxy.js +18 -12
  8. package/src/dynamic/dynamicRenderMixin.js +2 -2
  9. package/src/index.js +3 -14
  10. package/src/observer/reactive.js +5 -4
  11. package/src/observer/ref.js +3 -2
  12. package/src/observer/scheduler.js +4 -0
  13. package/src/observer/watch.js +5 -4
  14. package/src/platform/builtInMixins/directiveHelperMixin.ios.js +4 -1
  15. package/src/platform/builtInMixins/styleHelperMixin.ios.js +28 -25
  16. package/src/platform/createApp.ios.js +57 -23
  17. package/src/platform/createApp.js +7 -9
  18. package/src/platform/env/event.js +108 -0
  19. package/src/platform/env/index.ios.js +51 -0
  20. package/src/platform/env/index.js +8 -0
  21. package/src/platform/env/index.web.js +48 -0
  22. package/src/{external → platform/env}/vuePlugin.js +1 -1
  23. package/src/platform/export/index.js +1 -1
  24. package/src/platform/patch/{ali/getDefaultOptions.js → getDefaultOptions.ali.js} +3 -3
  25. package/src/platform/patch/{react/getDefaultOptions.ios.js → getDefaultOptions.ios.js} +264 -191
  26. package/src/platform/patch/{wx/getDefaultOptions.js → getDefaultOptions.js} +11 -7
  27. package/src/platform/patch/{web/getDefaultOptions.js → getDefaultOptions.web.js} +5 -5
  28. package/src/platform/patch/index.js +4 -21
  29. package/src/platform/patch/{ali/lifecycle.js → lifecycle/index.ali.js} +2 -0
  30. package/src/platform/patch/lifecycle/index.js +1 -0
  31. package/src/platform/patch/{swan/lifecycle.js → lifecycle/index.swan.js} +2 -0
  32. package/src/platform/patch/{web/lifecycle.js → lifecycle/index.web.js} +4 -0
  33. package/src/platform/patch/{wx/lifecycle.js → lifecycle/index.wx.js} +2 -0
  34. package/LICENSE +0 -433
  35. package/src/external/vue.js +0 -1
  36. package/src/external/vue.web.js +0 -6
  37. package/src/platform/patch/react/getDefaultOptions.js +0 -1
  38. package/src/platform/patch/swan/getDefaultOptions.js +0 -34
  39. /package/src/platform/export/{apiInject.js → inject.js} +0 -0
  40. /package/src/platform/export/{apiInject.web.js → inject.web.js} +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mpxjs/core",
3
- "version": "2.9.67",
3
+ "version": "2.9.69-beta.0",
4
4
  "description": "mpx runtime core",
5
5
  "keywords": [
6
6
  "miniprogram",
@@ -19,21 +19,24 @@
19
19
  ],
20
20
  "main": "src/index.js",
21
21
  "dependencies": {
22
- "@mpxjs/utils": "^2.9.67",
22
+ "@mpxjs/utils": "^2.9.69",
23
23
  "lodash": "^4.1.1",
24
24
  "miniprogram-api-typings": "^3.10.0"
25
25
  },
26
26
  "peerDependencies": {
27
27
  "@ant-design/react-native": "^5.1.3",
28
+ "@d11/react-native-fast-image": "^8.6.12",
28
29
  "@mpxjs/api-proxy": "^2.9.0",
29
30
  "@mpxjs/store": "^2.9.0",
30
- "@react-navigation/native": "^6.1.17",
31
- "@react-navigation/native-stack": "^6.9.26",
31
+ "@react-navigation/native": "^7.0.3",
32
+ "@react-navigation/stack": "^7.0.4",
32
33
  "react": "*",
33
34
  "react-native": "*",
35
+ "promise": "^8.3.0",
34
36
  "react-native-gesture-handler": "^2.19.0",
35
37
  "react-native-linear-gradient": "^2.8.3",
36
- "react-native-safe-area-context": "^4.10.1",
38
+ "react-native-safe-area-context": "^4.14.0",
39
+ "react-native-screens": "^4.1.0",
37
40
  "react-native-webview": "^13.10.5",
38
41
  "vue": "^2.7.10",
39
42
  "vue-demi": "^0.14.6",
@@ -59,10 +62,13 @@
59
62
  "react-native": {
60
63
  "optional": true
61
64
  },
65
+ "promise": {
66
+ "optional": true
67
+ },
62
68
  "@react-navigation/native": {
63
69
  "optional": true
64
70
  },
65
- "@react-navigation/native-stack": {
71
+ "@react-navigation/stack": {
66
72
  "optional": true
67
73
  },
68
74
  "@ant-design/react-native": {
@@ -71,6 +77,9 @@
71
77
  "react-native-safe-area-context": {
72
78
  "optional": true
73
79
  },
80
+ "react-native-screens": {
81
+ "optional": true
82
+ },
74
83
  "react-native-webview": {
75
84
  "optional": true
76
85
  },
@@ -79,6 +88,9 @@
79
88
  },
80
89
  "react-native-linear-gradient": {
81
90
  "optional": true
91
+ },
92
+ "@d11/react-native-fast-image": {
93
+ "optional": true
82
94
  }
83
95
  },
84
96
  "publishConfig": {
@@ -97,5 +109,5 @@
97
109
  "url": "https://github.com/didi/mpx/issues"
98
110
  },
99
111
  "sideEffects": false,
100
- "gitHead": "b23d3850c16543c5998811b8d1d8e6ee7988c0f8"
112
+ "gitHead": "2d37697869b9bdda3efab92dda8c910b68fd05c0"
101
113
  }
@@ -1,9 +1,6 @@
1
- import * as wxLifecycle from '../platform/patch/wx/lifecycle'
2
- import * as aliLifecycle from '../platform/patch/ali/lifecycle'
3
- import * as webLifecycle from '../platform/patch/web/lifecycle'
4
- import * as swanLifecycle from '../platform/patch/swan/lifecycle'
1
+ import { LIFECYCLE, lifecycleProxyMap, pageMode } from '../platform/patch/lifecycle/index'
5
2
  import { mergeLifecycle } from './mergeLifecycle'
6
- import { error } from '@mpxjs/utils'
3
+ import { error, extend } from '@mpxjs/utils'
7
4
  import wxToAliRule from './wxToAli'
8
5
  import wxToWebRule from './wxToWeb'
9
6
  import wxToSwanRule from './wxToSwan'
@@ -13,24 +10,6 @@ import wxToDdRule from './wxToDd'
13
10
  import wxToJdRule from './wxToJd'
14
11
  import wxToReactRule from './wxToReact'
15
12
 
16
- // 根据当前环境获取的默认生命周期信息
17
- let lifecycleInfo
18
- let pageMode
19
-
20
- if (__mpx_mode__ === 'web') {
21
- lifecycleInfo = webLifecycle
22
- pageMode = ''
23
- } else if (__mpx_mode__ === 'ali') {
24
- lifecycleInfo = aliLifecycle
25
- pageMode = ''
26
- } else if (__mpx_mode__ === 'swan') {
27
- lifecycleInfo = swanLifecycle
28
- pageMode = 'blend'
29
- } else {
30
- lifecycleInfo = wxLifecycle
31
- pageMode = 'blend'
32
- }
33
-
34
13
  /**
35
14
  * 转换规则包含四点
36
15
  * lifecycle [object] 生命周期
@@ -40,25 +19,25 @@ if (__mpx_mode__ === 'web') {
40
19
  * convert [function] 自定义转换函数, 接收一个options
41
20
  */
42
21
  const defaultConvertRule = {
43
- lifecycle: mergeLifecycle(lifecycleInfo.LIFECYCLE),
44
- lifecycleProxyMap: lifecycleInfo.lifecycleProxyMap,
22
+ lifecycle: mergeLifecycle(LIFECYCLE),
23
+ lifecycleProxyMap: lifecycleProxyMap,
45
24
  pageMode,
46
25
  support: !!pageMode,
47
26
  convert: null
48
27
  }
49
28
 
50
29
  const rulesMap = {
51
- local: { ...defaultConvertRule },
30
+ local: extend({}, defaultConvertRule),
52
31
  default: defaultConvertRule,
53
32
  wxToWeb: wxToWebRule,
54
33
  wxToAli: wxToAliRule,
55
34
  wxToSwan: wxToSwanRule,
56
- wxToQq: { ...defaultConvertRule, ...wxToQqRule },
57
- wxToTt: { ...defaultConvertRule, ...wxToTtRule },
58
- wxToDd: { ...defaultConvertRule, ...wxToDdRule },
59
- wxToJd: { ...defaultConvertRule, ...wxToJdRule },
60
- wxToIos: { ...defaultConvertRule, ...wxToReactRule },
61
- wxToAndroid: { ...defaultConvertRule, ...wxToReactRule }
35
+ wxToQq: extend({}, defaultConvertRule, wxToQqRule),
36
+ wxToTt: extend({}, defaultConvertRule, wxToTtRule),
37
+ wxToDd: extend({}, defaultConvertRule, wxToDdRule),
38
+ wxToJd: extend({}, defaultConvertRule, wxToJdRule),
39
+ wxToIos: extend({}, defaultConvertRule, wxToReactRule),
40
+ wxToAndroid: extend({}, defaultConvertRule, wxToReactRule)
62
41
  }
63
42
 
64
43
  export function getConvertRule (convertMode) {
@@ -1,5 +1,5 @@
1
- import * as wxLifecycle from '../platform/patch/wx/lifecycle'
2
- import * as aliLifecycle from '../platform/patch/ali/lifecycle'
1
+ import * as wxLifecycle from '../platform/patch/lifecycle/index.wx'
2
+ import { LIFECYCLE } from '../platform/patch/lifecycle/index'
3
3
  import { mergeLifecycle } from './mergeLifecycle'
4
4
  import { error, hasOwn, isDev } from '@mpxjs/utils'
5
5
  import { implemented } from '../core/implement'
@@ -38,7 +38,7 @@ function notSupportTip (options) {
38
38
 
39
39
  export default {
40
40
  lifecycle: mergeLifecycle(wxLifecycle.LIFECYCLE),
41
- lifecycle2: mergeLifecycle(aliLifecycle.LIFECYCLE),
41
+ lifecycle2: mergeLifecycle(LIFECYCLE),
42
42
  pageMode: 'blend',
43
43
  support: false,
44
44
  lifecycleProxyMap: wxLifecycle.lifecycleProxyMap,
@@ -5,7 +5,7 @@ import {
5
5
  import { implemented } from '../core/implement'
6
6
 
7
7
  // 暂不支持的wx选项,后期需要各种花式支持
8
- const unsupported = ['relations', 'moved', 'definitionFilter', 'onShareAppMessage']
8
+ const unsupported = ['relations', 'moved', 'definitionFilter']
9
9
 
10
10
  function convertErrorDesc (key) {
11
11
  error(`Options.${key} is not supported in runtime conversion from wx to react native.`, global.currentResource)
@@ -1,8 +1,8 @@
1
1
  import { error, isDev } from '@mpxjs/utils'
2
2
  import { implemented } from '../core/implement'
3
3
  import { mergeLifecycle } from './mergeLifecycle'
4
- import * as wxLifecycle from '../platform/patch/wx/lifecycle'
5
- import * as swanLifecycle from '../platform/patch/swan/lifecycle'
4
+ import * as wxLifecycle from '../platform/patch/lifecycle/index.wx'
5
+ import { LIFECYCLE } from '../platform/patch/lifecycle/index'
6
6
 
7
7
  const BEHAVIORS_MAP = {
8
8
  'wx://form-field': 'swan://form-field',
@@ -30,7 +30,7 @@ function notSupportTip (options) {
30
30
 
31
31
  export default {
32
32
  lifecycle: mergeLifecycle(wxLifecycle.LIFECYCLE),
33
- lifecycle2: mergeLifecycle(swanLifecycle.LIFECYCLE),
33
+ lifecycle2: mergeLifecycle(LIFECYCLE),
34
34
  pageMode: 'blend',
35
35
  support: true,
36
36
  lifecycleProxyMap: wxLifecycle.lifecycleProxyMap,
@@ -1,5 +1,5 @@
1
- import * as wxLifecycle from '../platform/patch/wx/lifecycle'
2
- import * as webLifecycle from '../platform/patch/web/lifecycle'
1
+ import * as wxLifecycle from '../platform/patch/lifecycle/index.wx'
2
+ import { LIFECYCLE } from '../platform/patch/lifecycle/index'
3
3
  import { mergeLifecycle } from './mergeLifecycle'
4
4
  import {
5
5
  isObject,
@@ -32,7 +32,7 @@ function notSupportTip (options) {
32
32
 
33
33
  export default {
34
34
  lifecycle: mergeLifecycle(wxLifecycle.LIFECYCLE),
35
- lifecycle2: mergeLifecycle(webLifecycle.LIFECYCLE),
35
+ lifecycle2: mergeLifecycle(LIFECYCLE),
36
36
  pageMode: 'blend',
37
37
  support: true,
38
38
  lifecycleProxyMap: wxLifecycle.lifecycleProxyMap,
package/src/core/proxy.js CHANGED
@@ -14,6 +14,7 @@ import {
14
14
  isEmptyObject,
15
15
  isPlainObject,
16
16
  isWeb,
17
+ isReact,
17
18
  doGetByPath,
18
19
  getByPath,
19
20
  setByPath,
@@ -50,7 +51,7 @@ import {
50
51
  } from './innerLifecycle'
51
52
  import contextMap from '../dynamic/vnode/context'
52
53
  import { getAst } from '../dynamic/astCache'
53
- import { inject, provide } from '../platform/export/apiInject'
54
+ import { inject, provide } from '../platform/export/inject'
54
55
 
55
56
  let uid = 0
56
57
 
@@ -116,7 +117,7 @@ export default class MpxProxy {
116
117
  this.ignoreProxyMap = makeMap(Mpx.config.ignoreProxyWhiteList)
117
118
  // 收集setup中动态注册的hooks,小程序与web环境都需要
118
119
  this.hooks = {}
119
- if (__mpx_mode__ !== 'web') {
120
+ if (!isWeb) {
120
121
  this.scope = effectScope(true)
121
122
  // props响应式数据代理
122
123
  this.props = {}
@@ -134,8 +135,12 @@ export default class MpxProxy {
134
135
  this.forceUpdateAll = false
135
136
  this.currentRenderTask = null
136
137
  this.propsUpdatedFlag = false
137
- // react专用,正确触发updated钩子
138
- this.pendingUpdatedFlag = false
138
+ if (isReact) {
139
+ // react专用,正确触发updated钩子
140
+ this.pendingUpdatedFlag = false
141
+ this.memoVersion = Symbol()
142
+ this.finalMemoVersion = Symbol()
143
+ }
139
144
  }
140
145
  this.initApi()
141
146
  }
@@ -160,7 +165,7 @@ export default class MpxProxy {
160
165
  // 缓存上下文,在 destoryed 阶段删除
161
166
  contextMap.set(this.uid, this.target)
162
167
  }
163
- if (__mpx_mode__ !== 'web') {
168
+ if (!isWeb) {
164
169
  // web中BEFORECREATE钩子通过vue的beforeCreate钩子单独驱动
165
170
  this.callHook(BEFORECREATE)
166
171
  setCurrentInstance(this)
@@ -179,7 +184,7 @@ export default class MpxProxy {
179
184
  this.state = CREATED
180
185
  this.callHook(CREATED)
181
186
 
182
- if (__mpx_mode__ !== 'web' && __mpx_mode__ !== 'ios' && __mpx_mode__ !== 'android') {
187
+ if (!isWeb && !isReact) {
183
188
  this.initRender()
184
189
  }
185
190
 
@@ -272,7 +277,7 @@ export default class MpxProxy {
272
277
  }
273
278
  // 挂载$rawOptions
274
279
  this.target.$rawOptions = this.options
275
- if (__mpx_mode__ !== 'web') {
280
+ if (!isWeb) {
276
281
  // 挂载$watch
277
282
  this.target.$watch = this.watch.bind(this)
278
283
  // 强制执行render
@@ -282,13 +287,14 @@ export default class MpxProxy {
282
287
  }
283
288
 
284
289
  initProps () {
285
- if (__mpx_mode__ === 'ios' || __mpx_mode__ === 'android') {
290
+ if (isReact) {
286
291
  // react模式下props内部对象透传无需深clone,依赖对象深层的数据响应触发子组件更新
287
292
  this.props = this.target.__getProps()
293
+ reactive(this.processIgnoreReactive(this.props))
288
294
  } else {
289
295
  this.props = diffAndCloneA(this.target.__getProps(this.options)).clone
296
+ reactive(this.processIgnoreReactive(this.props))
290
297
  }
291
- reactive(this.processIgnoreReactive(this.props))
292
298
  proxy(this.target, this.props, undefined, false, this.createProxyConflictHandler('props'))
293
299
  }
294
300
 
@@ -562,7 +568,7 @@ export default class MpxProxy {
562
568
  }
563
569
  if (!processed) {
564
570
  // 如果当前数据和上次的miniRenderData完全无关,但存在于组件的视图数据中,则与组件视图数据进行diff
565
- if (this.target.data && hasOwn(this.target.data, firstKey)) {
571
+ if (hasOwn(this.target.data, firstKey)) {
566
572
  const localInitialData = getByPath(this.target.data, key)
567
573
  const { clone, diff, diffData } = diffAndCloneA(data, localInitialData)
568
574
  this.miniRenderData[key] = clone
@@ -755,12 +761,12 @@ export default class MpxProxy {
755
761
  }
756
762
  setByPath(this.target, key, data[key])
757
763
  })
758
- this.forceUpdateData = data
764
+ Object.assign(this.forceUpdateData, data)
759
765
  } else {
760
766
  this.forceUpdateAll = true
761
767
  }
762
768
 
763
- if (__mpx_mode__ === 'ios' || __mpx_mode__ === 'android') {
769
+ if (isReact) {
764
770
  // rn中不需要setdata
765
771
  this.forceUpdateData = {}
766
772
  this.forceUpdateAll = false
@@ -1,4 +1,4 @@
1
- import { hasOwn, isObject, error } from '@mpxjs/utils'
1
+ import { hasOwn, error } from '@mpxjs/utils'
2
2
  import genVnodeTree from './vnode/render'
3
3
  import contextMap from './vnode/context'
4
4
  import { CREATED } from '../core/innerLifecycle'
@@ -56,7 +56,7 @@ function dynamicRenderHelperMixin () {
56
56
  methods: {
57
57
  _g (astData, moduleId) {
58
58
  const location = this.__mpxProxy && this.__mpxProxy.options.mpxFileResource
59
- if (astData && isObject(astData) && hasOwn(astData, 'template')) {
59
+ if (hasOwn(astData, 'template')) {
60
60
  const vnodeTree = genVnodeTree(astData, [this], { moduleId, location })
61
61
  return vnodeTree
62
62
  } else {
package/src/index.js CHANGED
@@ -1,8 +1,7 @@
1
- import Vue from './external/vue'
1
+
2
2
  import { error, diffAndCloneA, hasOwn, makeMap } from '@mpxjs/utils'
3
3
  import { APIs, InstanceAPIs } from './platform/export/api'
4
-
5
- import { createI18n } from './platform/builtInMixins/i18nMixin'
4
+ import { init } from './platform/env/index'
6
5
 
7
6
  export * from './platform/export/index'
8
7
 
@@ -123,10 +122,6 @@ function factory () {
123
122
 
124
123
  Object.assign(Mpx, APIs)
125
124
  Object.assign(Mpx.prototype, InstanceAPIs)
126
- // 输出web时在mpx上挂载Vue对象
127
- if (__mpx_mode__ === 'web') {
128
- Mpx.__vue = Vue
129
- }
130
125
  return Mpx
131
126
  }
132
127
 
@@ -156,12 +151,6 @@ Mpx.config = {
156
151
  rnConfig: {}
157
152
  }
158
153
 
159
- global.__mpx = Mpx
160
-
161
- if (__mpx_mode__ !== 'web') {
162
- if (global.i18n) {
163
- Mpx.i18n = createI18n(global.i18n)
164
- }
165
- }
154
+ init(Mpx)
166
155
 
167
156
  export default Mpx
@@ -34,6 +34,7 @@ export class Observer {
34
34
 
35
35
  constructor (value, shallow) {
36
36
  this.value = value
37
+ this.shallow = shallow
37
38
  def(value, ObKey, this)
38
39
  if (Array.isArray(value)) {
39
40
  const augment = hasProto && arrayProtoAugment
@@ -120,7 +121,7 @@ export function defineReactive (obj, key, val, shallow) {
120
121
  const getter = property && property.get
121
122
  const setter = property && property.set
122
123
 
123
- let childOb = !shallow && observe(val)
124
+ let childOb = shallow ? getObserver(val) : observe(val)
124
125
  Object.defineProperty(obj, key, {
125
126
  enumerable: true,
126
127
  configurable: true,
@@ -149,7 +150,7 @@ export function defineReactive (obj, key, val, shallow) {
149
150
  } else {
150
151
  val = newVal
151
152
  }
152
- childOb = !shallow && observe(newVal)
153
+ childOb = shallow ? getObserver(newVal) : observe(newVal)
153
154
  dep.notify()
154
155
  }
155
156
  })
@@ -175,7 +176,7 @@ export function set (target, key, val) {
175
176
  target[key] = val
176
177
  return val
177
178
  }
178
- defineReactive(ob.value, key, val)
179
+ defineReactive(ob.value, key, val, ob.shallow)
179
180
  ob.dep.notify()
180
181
  return val
181
182
  }
@@ -225,7 +226,7 @@ export function shallowReactive (value) {
225
226
  }
226
227
 
227
228
  export function isReactive (value) {
228
- return value && hasOwn(value, ObKey) && value[ObKey] instanceof Observer
229
+ return hasOwn(value, ObKey) && value[ObKey] instanceof Observer
229
230
  }
230
231
 
231
232
  export function getObserver (value) {
@@ -3,12 +3,13 @@ import { RefKey } from '../helper/const'
3
3
  import {
4
4
  warn,
5
5
  isPlainObject,
6
- hasOwn
6
+ hasOwn,
7
+ extend
7
8
  } from '@mpxjs/utils'
8
9
 
9
10
  export class RefImpl {
10
11
  constructor (options) {
11
- Object.defineProperty(this, 'value', { enumerable: true, ...options })
12
+ Object.defineProperty(this, 'value', extend({ enumerable: true }, options))
12
13
  }
13
14
  }
14
15
 
@@ -83,6 +83,10 @@ export function queueJob (job) {
83
83
  }
84
84
  }
85
85
 
86
+ export function hasPendingJob (job) {
87
+ return queue.length && queue.includes(job, isFlushing && job.allowRecurse ? flushIndex + 1 : flushIndex)
88
+ }
89
+
86
90
  function queueFlush () {
87
91
  if (!isFlushing && !isFlushPending) {
88
92
  isFlushPending = true
@@ -12,7 +12,8 @@ import {
12
12
  isArray,
13
13
  remove,
14
14
  callWithErrorHandling,
15
- hasChanged
15
+ hasChanged,
16
+ extend
16
17
  } from '@mpxjs/utils'
17
18
 
18
19
  export function watchEffect (effect, options) {
@@ -20,11 +21,11 @@ export function watchEffect (effect, options) {
20
21
  }
21
22
 
22
23
  export function watchPostEffect (effect, options) {
23
- return watch(effect, null, { ...options, flush: 'post' })
24
+ return watch(effect, null, extend({}, options, { flush: 'post' }))
24
25
  }
25
26
 
26
27
  export function watchSyncEffect (effect, options) {
27
- return watch(effect, null, { ...options, flush: 'sync' })
28
+ return watch(effect, null, extend({}, options, { flush: 'sync' }))
28
29
  }
29
30
 
30
31
  const warnInvalidSource = (s) => {
@@ -34,7 +35,7 @@ const warnInvalidSource = (s) => {
34
35
  const shouldTrigger = (value, oldValue) => hasChanged(value, oldValue) || isObject(value)
35
36
 
36
37
  const processWatchOptionsCompat = (options) => {
37
- const newOptions = { ...options }
38
+ const newOptions = extend({}, options)
38
39
  if (options.sync) {
39
40
  newOptions.flush = 'sync'
40
41
  }
@@ -1,7 +1,10 @@
1
1
  export default function directiveHelperMixin () {
2
2
  return {
3
3
  methods: {
4
- __getWxKey (item, key) {
4
+ __getWxKey (item, key, index) {
5
+ if (key === 'index') {
6
+ return index
7
+ }
5
8
  return key === '*this' ? item : item[key]
6
9
  }
7
10
  }
@@ -1,19 +1,22 @@
1
- import { isObject, isArray, dash2hump, isFunction, cached, getFocusedNavigation } from '@mpxjs/utils'
1
+ import { isObject, isArray, dash2hump, cached, isEmptyObject } from '@mpxjs/utils'
2
2
  import { Dimensions, StyleSheet } from 'react-native'
3
3
 
4
+ let { width, height } = Dimensions.get('screen')
5
+
6
+ Dimensions.addEventListener('change', ({ screen }) => {
7
+ width = screen.width
8
+ height = screen.height
9
+ })
10
+
4
11
  function rpx (value) {
5
- const { width } = Dimensions.get('screen')
6
12
  // rn 单位 dp = 1(css)px = 1 物理像素 * pixelRatio(像素比)
7
13
  // px = rpx * (750 / 屏幕宽度)
8
14
  return value * width / 750
9
15
  }
10
16
  function vw (value) {
11
- const { width } = Dimensions.get('screen')
12
17
  return value * width / 100
13
18
  }
14
19
  function vh (value) {
15
- const navigation = getFocusedNavigation()
16
- const height = navigation?.layout?.height || Dimensions.get('screen').height
17
20
  return value * height / 100
18
21
  }
19
22
 
@@ -23,15 +26,18 @@ const unit = {
23
26
  vh
24
27
  }
25
28
 
29
+ const empty = {}
30
+
26
31
  function formatValue (value) {
27
- let matched
28
- if ((matched = numberRegExp.exec(value))) {
29
- value = +matched[1]
30
- } else if ((matched = unitRegExp.exec(value))) {
31
- value = unit[matched[2]](+matched[1])
32
- } else if (hairlineRegExp.test(value)) {
33
- value = StyleSheet.hairlineWidth
32
+ const matched = unitRegExp.exec(value)
33
+ if (matched) {
34
+ if (!matched[2] || matched[2] === 'px') {
35
+ return +matched[1]
36
+ } else {
37
+ return unit[matched[2]](+matched[1])
38
+ }
34
39
  }
40
+ if (hairlineRegExp.test(value)) return StyleSheet.hairlineWidth
35
41
  return value
36
42
  }
37
43
 
@@ -106,8 +112,7 @@ function stringifyDynamicClass (value) {
106
112
 
107
113
  const listDelimiter = /;(?![^(]*[)])/g
108
114
  const propertyDelimiter = /:(.+)/
109
- const unitRegExp = /^\s*(-?\d+(?:\.\d+)?)(rpx|vw|vh)\s*$/
110
- const numberRegExp = /^\s*(-?\d+(\.\d+)?)(px)?\s*$/
115
+ const unitRegExp = /^\s*(-?\d+(?:\.\d+)?)(rpx|vw|vh|px)?\s*$/
111
116
  const hairlineRegExp = /^\s*hairlineWidth\s*$/
112
117
  const varRegExp = /^--/
113
118
 
@@ -164,14 +169,8 @@ export default function styleHelperMixin () {
164
169
  },
165
170
  __getStyle (staticClass, dynamicClass, staticStyle, dynamicStyle, hide) {
166
171
  const result = {}
167
- const classMap = {}
168
- // todo 全局样式在每个页面和组件中生效,以支持全局原子类,后续支持样式模块复用后可考虑移除
169
- if (isFunction(global.__getAppClassMap)) {
170
- Object.assign(classMap, global.__getAppClassMap())
171
- }
172
- if (isFunction(this.__getClassMap)) {
173
- Object.assign(classMap, this.__getClassMap())
174
- }
172
+ const classMap = this.__getClassMap?.() || {}
173
+ const appClassMap = global.__getAppClassMap?.() || {}
175
174
 
176
175
  if (staticClass || dynamicClass) {
177
176
  // todo 当前为了复用小程序unocss产物,暂时进行mpEscape,等后续正式支持unocss后可不进行mpEscape
@@ -179,9 +178,12 @@ export default function styleHelperMixin () {
179
178
  classString.split(/\s+/).forEach((className) => {
180
179
  if (classMap[className]) {
181
180
  Object.assign(result, classMap[className])
182
- } else if (this.props[className] && isObject(this.props[className])) {
181
+ } else if (appClassMap[className]) {
182
+ // todo 全局样式在每个页面和组件中生效,以支持全局原子类,后续支持样式模块复用后可考虑移除
183
+ Object.assign(result, appClassMap[className])
184
+ } else if (this.__props[className] && isObject(this.__props[className])) {
183
185
  // externalClasses必定以对象形式传递下来
184
- Object.assign(result, this.props[className])
186
+ Object.assign(result, this.__props[className])
185
187
  }
186
188
  })
187
189
  }
@@ -196,7 +198,8 @@ export default function styleHelperMixin () {
196
198
  display: 'none'
197
199
  })
198
200
  }
199
- return result
201
+
202
+ return isEmptyObject(result) ? empty : result
200
203
  }
201
204
  }
202
205
  }