@mpxjs/core 2.8.33 → 2.8.36

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mpxjs/core",
3
- "version": "2.8.33",
3
+ "version": "2.8.36",
4
4
  "description": "mpx runtime core",
5
5
  "keywords": [
6
6
  "miniprogram",
@@ -47,5 +47,5 @@
47
47
  "url": "https://github.com/didi/mpx/issues"
48
48
  },
49
49
  "sideEffects": false,
50
- "gitHead": "6838a99375bfce3ebd8046e86f8806920f4f2b37"
50
+ "gitHead": "f7d1fc9bf1aaf7aff6fe9f2a11288dc5e12f78d6"
51
51
  }
package/src/core/proxy.js CHANGED
@@ -1,9 +1,9 @@
1
1
  import { reactive } from '../observer/reactive'
2
- import { ReactiveEffect } from '../observer/effect'
2
+ import { ReactiveEffect, pauseTracking, resetTracking } from '../observer/effect'
3
3
  import { effectScope } from '../platform/export/index'
4
4
  import { watch } from '../observer/watch'
5
5
  import { computed } from '../observer/computed'
6
- import { queueJob, nextTick } from '../observer/scheduler'
6
+ import { queueJob, nextTick, flushPreFlushCbs } from '../observer/scheduler'
7
7
  import Mpx from '../index'
8
8
  import {
9
9
  noop,
@@ -119,6 +119,7 @@ export default class MpxProxy {
119
119
  // 下次是否需要强制更新全部渲染数据
120
120
  this.forceUpdateAll = false
121
121
  this.currentRenderTask = null
122
+ this.propsUpdatedFlag = false
122
123
  }
123
124
  this.initApi()
124
125
  }
@@ -170,7 +171,9 @@ export default class MpxProxy {
170
171
  }
171
172
 
172
173
  propsUpdated () {
174
+ this.propsUpdatedFlag = true
173
175
  const updateJob = this.updateJob || (this.updateJob = () => {
176
+ this.propsUpdatedFlag = false
174
177
  // 只有当前没有渲染任务时,属性更新才需要单独触发updated,否则可以由渲染任务触发updated
175
178
  if (this.currentRenderTask?.resolved && this.isMounted()) {
176
179
  this.callHook(BEFOREUPDATE)
@@ -477,6 +480,7 @@ export default class MpxProxy {
477
480
  return
478
481
  }
479
482
 
483
+ pauseTracking()
480
484
  // 使用forceUpdateData后清空
481
485
  if (!isEmptyObject(this.forceUpdateData)) {
482
486
  data = mergeData({}, data, this.forceUpdateData)
@@ -504,12 +508,30 @@ export default class MpxProxy {
504
508
  }
505
509
 
506
510
  this.target.__render(data, callback)
511
+ resetTracking()
512
+ }
513
+
514
+ toggleRecurse (allowed) {
515
+ if (this.effect && this.update) this.effect.allowRecurse = this.update.allowRecurse = allowed
516
+ }
517
+
518
+ updatePreRender () {
519
+ this.toggleRecurse(false)
520
+ pauseTracking()
521
+ flushPreFlushCbs(undefined, this.update)
522
+ resetTracking()
523
+ this.toggleRecurse(true)
507
524
  }
508
525
 
509
526
  initRender () {
510
527
  if (this.options.__nativeRender__) return this.doRender()
511
528
 
512
529
  const effect = this.effect = new ReactiveEffect(() => {
530
+ // pre render for props update
531
+ if (this.propsUpdatedFlag) {
532
+ this.updatePreRender()
533
+ }
534
+
513
535
  if (this.target.__injectedRender) {
514
536
  try {
515
537
  return this.target.__injectedRender()
@@ -522,10 +544,10 @@ export default class MpxProxy {
522
544
  }
523
545
  }, () => queueJob(update), this.scope)
524
546
 
525
- const update = this.update = this.effect.run.bind(this.effect)
547
+ const update = this.update = effect.run.bind(effect)
526
548
  update.id = this.uid
527
549
  // render effect允许自触发
528
- effect.allowRecurse = update.allowRecurse = true
550
+ this.toggleRecurse(true)
529
551
  update()
530
552
  }
531
553
 
@@ -4,6 +4,19 @@ import { PausedState } from '../helper/const'
4
4
 
5
5
  let uid = 0
6
6
 
7
+ let shouldTrack = true
8
+ const trackStack = []
9
+
10
+ export function pauseTracking () {
11
+ trackStack.push(shouldTrack)
12
+ shouldTrack = false
13
+ }
14
+
15
+ export function resetTracking () {
16
+ const last = trackStack.pop()
17
+ shouldTrack = last === undefined ? true : last
18
+ }
19
+
7
20
  export class ReactiveEffect {
8
21
  active = true
9
22
  deps = []
@@ -27,17 +40,21 @@ export class ReactiveEffect {
27
40
  // run fn and return value
28
41
  run () {
29
42
  if (!this.active) return this.fn()
30
- pushTarget(this)
43
+ const lastShouldTrack = shouldTrack
31
44
  try {
45
+ pushTarget(this)
46
+ shouldTrack = true
32
47
  return this.fn()
33
48
  } finally {
34
49
  popTarget()
50
+ shouldTrack = lastShouldTrack
35
51
  this.deferStop ? this.stop() : this.cleanupDeps()
36
52
  }
37
53
  }
38
54
 
39
55
  // add dependency to this
40
56
  addDep (dep) {
57
+ if (!shouldTrack) return
41
58
  const id = dep.id
42
59
  if (!this.newDepIds.has(id)) {
43
60
  this.newDepIds.add(id)
@@ -17,6 +17,7 @@ let postFlushIndex = 0
17
17
 
18
18
  const resolvedPromise = Promise.resolve()
19
19
  let currentFlushPromise = null
20
+ let currentPreFlushParentJob = null
20
21
 
21
22
  const RECURSION_LIMIT = 100
22
23
 
@@ -68,9 +69,9 @@ export function queueJob (job) {
68
69
  // if the job is a watch() callback, the search will start with a +1 index to
69
70
  // allow it recursively trigger itself - it is the user's responsibility to
70
71
  // ensure it doesn't end up in an infinite loop.
71
- if (
72
- !queue.length ||
73
- !queue.includes(job, isFlushing && job.allowRecurse ? flushIndex + 1 : flushIndex)
72
+ if ((!queue.length ||
73
+ !queue.includes(job, isFlushing && job.allowRecurse ? flushIndex + 1 : flushIndex)) &&
74
+ job !== currentPreFlushParentJob
74
75
  ) {
75
76
  if (job.id == null) {
76
77
  queue.push(job)
@@ -92,8 +93,9 @@ function queueFlush () {
92
93
  }
93
94
  }
94
95
 
95
- export function flushPreFlushCbs (seen) {
96
+ export function flushPreFlushCbs (seen, parentJob = null) {
96
97
  if (pendingPreFlushCbs.length) {
98
+ currentPreFlushParentJob = parentJob
97
99
  activePreFlushCbs = [...new Set(pendingPreFlushCbs)]
98
100
  pendingPreFlushCbs.length = 0
99
101
  if (isDev) seen = seen || new Map()
@@ -107,8 +109,9 @@ export function flushPreFlushCbs (seen) {
107
109
  }
108
110
  activePreFlushCbs = null
109
111
  preFlushIndex = 0
112
+ currentPreFlushParentJob = null
110
113
  // recursively flush until it drains
111
- flushPreFlushCbs(seen)
114
+ flushPreFlushCbs(seen, parentJob)
112
115
  }
113
116
  }
114
117