vue 2.7.1 → 2.7.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 (42) hide show
  1. package/dist/vue.common.dev.js +133 -61
  2. package/dist/vue.common.prod.js +3 -3
  3. package/dist/vue.esm.browser.js +133 -62
  4. package/dist/vue.esm.browser.min.js +3 -3
  5. package/dist/vue.esm.js +135 -62
  6. package/dist/vue.js +135 -61
  7. package/dist/vue.min.js +3 -3
  8. package/dist/vue.runtime.common.dev.js +133 -61
  9. package/dist/vue.runtime.common.prod.js +3 -3
  10. package/dist/vue.runtime.esm.js +135 -62
  11. package/dist/vue.runtime.js +135 -61
  12. package/dist/vue.runtime.min.js +3 -3
  13. package/dist/vue.runtime.mjs +72 -8604
  14. package/package.json +2 -2
  15. package/packages/compiler-sfc/dist/compiler-sfc.js +56 -55
  16. package/packages/compiler-sfc/package.json +1 -1
  17. package/packages/compiler-sfc/src/parseComponent.ts +9 -1
  18. package/packages/compiler-sfc/test/parseComponent.spec.ts +6 -7
  19. package/src/core/instance/render-helpers/render-static.ts +1 -1
  20. package/src/core/observer/index.ts +54 -55
  21. package/src/core/util/next-tick.ts +2 -1
  22. package/src/core/vdom/modules/directives.ts +2 -2
  23. package/src/shared/constants.ts +3 -1
  24. package/src/v3/apiAsyncComponent.ts +117 -0
  25. package/src/v3/apiWatch.ts +2 -2
  26. package/src/v3/index.ts +6 -0
  27. package/src/v3/reactivity/reactive.ts +13 -2
  28. package/src/v3/reactivity/ref.ts +6 -2
  29. package/types/common.d.ts +6 -0
  30. package/types/index.d.ts +7 -4
  31. package/types/jsx.d.ts +16 -2
  32. package/types/options.d.ts +8 -2
  33. package/types/v3-component-options.d.ts +162 -33
  34. package/types/v3-component-props.d.ts +19 -20
  35. package/types/v3-component-public-instance.d.ts +234 -0
  36. package/types/v3-define-async-component.d.ts +26 -0
  37. package/types/v3-define-component.d.ts +94 -12
  38. package/types/v3-generated.d.ts +26 -1
  39. package/types/v3-setup-context.d.ts +0 -6
  40. package/types/vnode.d.ts +15 -0
  41. package/types/vue.d.ts +17 -10
  42. package/types/v3-component-proxy.d.ts +0 -189
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vue",
3
- "version": "2.7.1",
3
+ "version": "2.7.4",
4
4
  "packageManager": "pnpm@7.1.0",
5
5
  "description": "Reactive, component-oriented view layer for modern web interfaces.",
6
6
  "main": "dist/vue.runtime.common.js",
@@ -60,7 +60,7 @@
60
60
  },
61
61
  "homepage": "https://github.com/vuejs/vue#readme",
62
62
  "dependencies": {
63
- "@vue/compiler-sfc": "2.7.1",
63
+ "@vue/compiler-sfc": "2.7.4",
64
64
  "csstype": "^3.1.0"
65
65
  },
66
66
  "devDependencies": {
@@ -740,7 +740,11 @@ function parseComponent(source, options = {}) {
740
740
  if (depth === 1 && currentBlock) {
741
741
  currentBlock.end = start;
742
742
  let text = source.slice(currentBlock.start, currentBlock.end);
743
- if (options.deindent) {
743
+ if (options.deindent === true ||
744
+ // by default, deindent unless it's script with default lang or ts
745
+ (options.deindent !== false &&
746
+ !(currentBlock.type === 'script' &&
747
+ (!currentBlock.lang || currentBlock.lang === 'ts')))) {
744
748
  text = deIndent(text);
745
749
  }
746
750
  // pad content so that linters and pre-processors can output correct
@@ -3347,7 +3351,9 @@ const LIFECYCLE_HOOKS = [
3347
3351
  'activated',
3348
3352
  'deactivated',
3349
3353
  'errorCaptured',
3350
- 'serverPrefetch'
3354
+ 'serverPrefetch',
3355
+ 'renderTracked',
3356
+ 'renderTriggered'
3351
3357
  ];
3352
3358
 
3353
3359
  var config = {
@@ -4357,7 +4363,7 @@ function renderStatic(index, isInFor) {
4357
4363
  return tree;
4358
4364
  }
4359
4365
  // otherwise, render a fresh tree.
4360
- tree = cached[index] = this.$options.staticRenderFns[index].call(this._renderProxy, null, this // for render fns generated for functional component templates
4366
+ tree = cached[index] = this.$options.staticRenderFns[index].call(this._renderProxy, this._c, this // for render fns generated for functional component templates
4361
4367
  );
4362
4368
  markStatic$1(tree, `__static__${index}`, false);
4363
4369
  return tree;
@@ -5186,6 +5192,13 @@ let shouldObserve = true;
5186
5192
  function toggleObserving(value) {
5187
5193
  shouldObserve = value;
5188
5194
  }
5195
+ // ssr mock dep
5196
+ const mockDep = {
5197
+ notify: noop,
5198
+ depend: noop,
5199
+ addSub: noop,
5200
+ removeSub: noop
5201
+ };
5189
5202
  /**
5190
5203
  * Observer class that is attached to each observed
5191
5204
  * object. Once attached, the observer converts the target
@@ -5193,76 +5206,60 @@ function toggleObserving(value) {
5193
5206
  * collect dependencies and dispatch updates.
5194
5207
  */
5195
5208
  class Observer {
5196
- constructor(value, shallow = false) {
5209
+ constructor(value, shallow = false, mock = false) {
5197
5210
  this.value = value;
5198
5211
  this.shallow = shallow;
5212
+ this.mock = mock;
5199
5213
  // this.value = value
5200
- this.dep = new Dep();
5214
+ this.dep = mock ? mockDep : new Dep();
5201
5215
  this.vmCount = 0;
5202
5216
  def(value, '__ob__', this);
5203
5217
  if (isArray(value)) {
5204
- if (hasProto) {
5205
- protoAugment(value, arrayMethods);
5206
- }
5207
- else {
5208
- copyAugment(value, arrayMethods, arrayKeys);
5218
+ if (!mock) {
5219
+ if (hasProto) {
5220
+ value.__proto__ = arrayMethods;
5221
+ /* eslint-enable no-proto */
5222
+ }
5223
+ else {
5224
+ for (let i = 0, l = arrayKeys.length; i < l; i++) {
5225
+ const key = arrayKeys[i];
5226
+ def(value, key, arrayMethods[key]);
5227
+ }
5228
+ }
5209
5229
  }
5210
5230
  if (!shallow) {
5211
5231
  this.observeArray(value);
5212
5232
  }
5213
5233
  }
5214
5234
  else {
5215
- this.walk(value, shallow);
5216
- }
5217
- }
5218
- /**
5219
- * Walk through all properties and convert them into
5220
- * getter/setters. This method should only be called when
5221
- * value type is Object.
5222
- */
5223
- walk(obj, shallow) {
5224
- const keys = Object.keys(obj);
5225
- for (let i = 0; i < keys.length; i++) {
5226
- const key = keys[i];
5227
- defineReactive(obj, key, NO_INIITIAL_VALUE, undefined, shallow);
5235
+ /**
5236
+ * Walk through all properties and convert them into
5237
+ * getter/setters. This method should only be called when
5238
+ * value type is Object.
5239
+ */
5240
+ const keys = Object.keys(value);
5241
+ for (let i = 0; i < keys.length; i++) {
5242
+ const key = keys[i];
5243
+ defineReactive(value, key, NO_INIITIAL_VALUE, undefined, shallow, mock);
5244
+ }
5228
5245
  }
5229
5246
  }
5230
5247
  /**
5231
5248
  * Observe a list of Array items.
5232
5249
  */
5233
- observeArray(items) {
5234
- for (let i = 0, l = items.length; i < l; i++) {
5235
- observe(items[i]);
5250
+ observeArray(value) {
5251
+ for (let i = 0, l = value.length; i < l; i++) {
5252
+ observe(value[i], false, this.mock);
5236
5253
  }
5237
5254
  }
5238
5255
  }
5239
5256
  // helpers
5240
- /**
5241
- * Augment a target Object or Array by intercepting
5242
- * the prototype chain using __proto__
5243
- */
5244
- function protoAugment(target, src) {
5245
- /* eslint-disable no-proto */
5246
- target.__proto__ = src;
5247
- /* eslint-enable no-proto */
5248
- }
5249
- /**
5250
- * Augment a target Object or Array by defining
5251
- * hidden properties.
5252
- */
5253
- /* istanbul ignore next */
5254
- function copyAugment(target, src, keys) {
5255
- for (let i = 0, l = keys.length; i < l; i++) {
5256
- const key = keys[i];
5257
- def(target, key, src[key]);
5258
- }
5259
- }
5260
5257
  /**
5261
5258
  * Attempt to create an observer instance for a value,
5262
5259
  * returns the new observer if successfully observed,
5263
5260
  * or the existing observer if the value already has one.
5264
5261
  */
5265
- function observe(value, shallow) {
5262
+ function observe(value, shallow, ssrMockReactivity) {
5266
5263
  if (!isObject$1(value) || isRef(value) || value instanceof VNode) {
5267
5264
  return;
5268
5265
  }
@@ -5271,18 +5268,18 @@ function observe(value, shallow) {
5271
5268
  ob = value.__ob__;
5272
5269
  }
5273
5270
  else if (shouldObserve &&
5274
- !isServerRendering() &&
5271
+ (ssrMockReactivity || !isServerRendering()) &&
5275
5272
  (isArray(value) || isPlainObject(value)) &&
5276
5273
  Object.isExtensible(value) &&
5277
- !value.__v_skip) {
5278
- ob = new Observer(value, shallow);
5274
+ !value.__v_skip /* ReactiveFlags.SKIP */) {
5275
+ ob = new Observer(value, shallow, ssrMockReactivity);
5279
5276
  }
5280
5277
  return ob;
5281
5278
  }
5282
5279
  /**
5283
5280
  * Define a reactive property on an Object.
5284
5281
  */
5285
- function defineReactive(obj, key, val, customSetter, shallow) {
5282
+ function defineReactive(obj, key, val, customSetter, shallow, mock) {
5286
5283
  const dep = new Dep();
5287
5284
  const property = Object.getOwnPropertyDescriptor(obj, key);
5288
5285
  if (property && property.configurable === false) {
@@ -5295,7 +5292,7 @@ function defineReactive(obj, key, val, customSetter, shallow) {
5295
5292
  (val === NO_INIITIAL_VALUE || arguments.length === 2)) {
5296
5293
  val = obj[key];
5297
5294
  }
5298
- let childOb = !shallow && observe(val);
5295
+ let childOb = !shallow && observe(val, false, mock);
5299
5296
  Object.defineProperty(obj, key, {
5300
5297
  enumerable: true,
5301
5298
  configurable: true,
@@ -5343,7 +5340,7 @@ function defineReactive(obj, key, val, customSetter, shallow) {
5343
5340
  else {
5344
5341
  val = newVal;
5345
5342
  }
5346
- childOb = !shallow && observe(newVal);
5343
+ childOb = !shallow && observe(newVal, false, mock);
5347
5344
  if (process.env.NODE_ENV !== 'production') {
5348
5345
  dep.notify({
5349
5346
  type: "set" /* TriggerOpTypes.SET */,
@@ -5368,16 +5365,20 @@ function set(target, key, val) {
5368
5365
  process.env.NODE_ENV !== 'production' && warn$3(`Set operation on key "${key}" failed: target is readonly.`);
5369
5366
  return;
5370
5367
  }
5368
+ const ob = target.__ob__;
5371
5369
  if (isArray(target) && isValidArrayIndex(key)) {
5372
5370
  target.length = Math.max(target.length, key);
5373
5371
  target.splice(key, 1, val);
5372
+ // when mocking for SSR, array methods are not hijacked
5373
+ if (ob && !ob.shallow && ob.mock) {
5374
+ observe(val, false, true);
5375
+ }
5374
5376
  return val;
5375
5377
  }
5376
5378
  if (key in target && !(key in Object.prototype)) {
5377
5379
  target[key] = val;
5378
5380
  return val;
5379
5381
  }
5380
- const ob = target.__ob__;
5381
5382
  if (target._isVue || (ob && ob.vmCount)) {
5382
5383
  process.env.NODE_ENV !== 'production' &&
5383
5384
  warn$3('Avoid adding reactive properties to a Vue instance or its root $data ' +
@@ -5388,7 +5389,7 @@ function set(target, key, val) {
5388
5389
  target[key] = val;
5389
5390
  return val;
5390
5391
  }
5391
- defineReactive(ob.value, key, val);
5392
+ defineReactive(ob.value, key, val, undefined, ob.shallow, ob.mock);
5392
5393
  if (process.env.NODE_ENV !== 'production') {
5393
5394
  ob.dep.notify({
5394
5395
  type: "add" /* TriggerOpTypes.ADD */,
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vue/compiler-sfc",
3
- "version": "2.7.1",
3
+ "version": "2.7.4",
4
4
  "description": "compiler-sfc for Vue 2",
5
5
  "main": "dist/compiler-sfc.js",
6
6
  "types": "dist/compiler-sfc.d.ts",
@@ -177,7 +177,15 @@ export function parseComponent(
177
177
  if (depth === 1 && currentBlock) {
178
178
  currentBlock.end = start
179
179
  let text = source.slice(currentBlock.start, currentBlock.end)
180
- if (options.deindent) {
180
+ if (
181
+ options.deindent === true ||
182
+ // by default, deindent unless it's script with default lang or ts
183
+ (options.deindent !== false &&
184
+ !(
185
+ currentBlock.type === 'script' &&
186
+ (!currentBlock.lang || currentBlock.lang === 'ts')
187
+ ))
188
+ ) {
181
189
  text = deindent(text)
182
190
  }
183
191
  // pad content so that linters and pre-processors can output correct
@@ -25,8 +25,7 @@ describe('Single File Component parser', () => {
25
25
  <div>
26
26
  <style>nested should be ignored</style>
27
27
  </div>
28
- `,
29
- { deindent: true }
28
+ `
30
29
  )
31
30
  expect(res.template!.content.trim()).toBe('<div>hi</div>')
32
31
  expect(res.styles.length).toBe(4)
@@ -76,8 +75,7 @@ describe('Single File Component parser', () => {
76
75
  </style>
77
76
  `
78
77
  const deindentDefault = parseComponent(content.trim(), {
79
- pad: false,
80
- deindent: true
78
+ pad: false
81
79
  })
82
80
  const deindentEnabled = parseComponent(content.trim(), {
83
81
  pad: false,
@@ -89,7 +87,9 @@ describe('Single File Component parser', () => {
89
87
  })
90
88
 
91
89
  expect(deindentDefault.template!.content).toBe('\n<div></div>\n')
92
- expect(deindentDefault.script!.content).toBe('\nexport default {}\n')
90
+ expect(deindentDefault.script!.content).toBe(
91
+ '\n export default {}\n '
92
+ )
93
93
  expect(deindentDefault.styles[0].content).toBe('\nh1 { color: red }\n')
94
94
  expect(deindentEnabled.template!.content).toBe('\n<div></div>\n')
95
95
  expect(deindentEnabled.script!.content).toBe('\nexport default {}\n')
@@ -203,8 +203,7 @@ describe('Single File Component parser', () => {
203
203
  }
204
204
  </test>
205
205
  <custom src="./x.json"></custom>
206
- `,
207
- { deindent: true }
206
+ `
208
207
  )
209
208
  expect(res.customBlocks.length).toBe(4)
210
209
 
@@ -18,7 +18,7 @@ export function renderStatic(
18
18
  // otherwise, render a fresh tree.
19
19
  tree = cached[index] = this.$options.staticRenderFns[index].call(
20
20
  this._renderProxy,
21
- null,
21
+ this._c,
22
22
  this // for render fns generated for functional component templates
23
23
  )
24
24
  markStatic(tree, `__static__${index}`, false)
@@ -13,7 +13,8 @@ import {
13
13
  isUndef,
14
14
  isValidArrayIndex,
15
15
  isServerRendering,
16
- hasChanged
16
+ hasChanged,
17
+ noop
17
18
  } from '../util/index'
18
19
  import { isReadonly, isRef, TrackOpTypes, TriggerOpTypes } from '../../v3'
19
20
 
@@ -31,6 +32,14 @@ export function toggleObserving(value: boolean) {
31
32
  shouldObserve = value
32
33
  }
33
34
 
35
+ // ssr mock dep
36
+ const mockDep = {
37
+ notify: noop,
38
+ depend: noop,
39
+ addSub: noop,
40
+ removeSub: noop
41
+ } as Dep
42
+
34
43
  /**
35
44
  * Observer class that is attached to each observed
36
45
  * object. Once attached, the observer converts the target
@@ -41,78 +50,63 @@ export class Observer {
41
50
  dep: Dep
42
51
  vmCount: number // number of vms that have this object as root $data
43
52
 
44
- constructor(public value: any, public shallow = false) {
53
+ constructor(public value: any, public shallow = false, public mock = false) {
45
54
  // this.value = value
46
- this.dep = new Dep()
55
+ this.dep = mock ? mockDep : new Dep()
47
56
  this.vmCount = 0
48
57
  def(value, '__ob__', this)
49
58
  if (isArray(value)) {
50
- if (hasProto) {
51
- protoAugment(value, arrayMethods)
52
- } else {
53
- copyAugment(value, arrayMethods, arrayKeys)
59
+ if (!mock) {
60
+ if (hasProto) {
61
+ /* eslint-disable no-proto */
62
+ ;(value as any).__proto__ = arrayMethods
63
+ /* eslint-enable no-proto */
64
+ } else {
65
+ for (let i = 0, l = arrayKeys.length; i < l; i++) {
66
+ const key = arrayKeys[i]
67
+ def(value, key, arrayMethods[key])
68
+ }
69
+ }
54
70
  }
55
71
  if (!shallow) {
56
72
  this.observeArray(value)
57
73
  }
58
74
  } else {
59
- this.walk(value, shallow)
60
- }
61
- }
62
-
63
- /**
64
- * Walk through all properties and convert them into
65
- * getter/setters. This method should only be called when
66
- * value type is Object.
67
- */
68
- walk(obj: object, shallow: boolean) {
69
- const keys = Object.keys(obj)
70
- for (let i = 0; i < keys.length; i++) {
71
- const key = keys[i]
72
- defineReactive(obj, key, NO_INIITIAL_VALUE, undefined, shallow)
75
+ /**
76
+ * Walk through all properties and convert them into
77
+ * getter/setters. This method should only be called when
78
+ * value type is Object.
79
+ */
80
+ const keys = Object.keys(value)
81
+ for (let i = 0; i < keys.length; i++) {
82
+ const key = keys[i]
83
+ defineReactive(value, key, NO_INIITIAL_VALUE, undefined, shallow, mock)
84
+ }
73
85
  }
74
86
  }
75
87
 
76
88
  /**
77
89
  * Observe a list of Array items.
78
90
  */
79
- observeArray(items: Array<any>) {
80
- for (let i = 0, l = items.length; i < l; i++) {
81
- observe(items[i])
91
+ observeArray(value: any[]) {
92
+ for (let i = 0, l = value.length; i < l; i++) {
93
+ observe(value[i], false, this.mock)
82
94
  }
83
95
  }
84
96
  }
85
97
 
86
98
  // helpers
87
99
 
88
- /**
89
- * Augment a target Object or Array by intercepting
90
- * the prototype chain using __proto__
91
- */
92
- function protoAugment(target, src: Object) {
93
- /* eslint-disable no-proto */
94
- target.__proto__ = src
95
- /* eslint-enable no-proto */
96
- }
97
-
98
- /**
99
- * Augment a target Object or Array by defining
100
- * hidden properties.
101
- */
102
- /* istanbul ignore next */
103
- function copyAugment(target: Object, src: Object, keys: Array<string>) {
104
- for (let i = 0, l = keys.length; i < l; i++) {
105
- const key = keys[i]
106
- def(target, key, src[key])
107
- }
108
- }
109
-
110
100
  /**
111
101
  * Attempt to create an observer instance for a value,
112
102
  * returns the new observer if successfully observed,
113
103
  * or the existing observer if the value already has one.
114
104
  */
115
- export function observe(value: any, shallow?: boolean): Observer | void {
105
+ export function observe(
106
+ value: any,
107
+ shallow?: boolean,
108
+ ssrMockReactivity?: boolean
109
+ ): Observer | void {
116
110
  if (!isObject(value) || isRef(value) || value instanceof VNode) {
117
111
  return
118
112
  }
@@ -121,12 +115,12 @@ export function observe(value: any, shallow?: boolean): Observer | void {
121
115
  ob = value.__ob__
122
116
  } else if (
123
117
  shouldObserve &&
124
- !isServerRendering() &&
118
+ (ssrMockReactivity || !isServerRendering()) &&
125
119
  (isArray(value) || isPlainObject(value)) &&
126
120
  Object.isExtensible(value) &&
127
- !value.__v_skip
121
+ !value.__v_skip /* ReactiveFlags.SKIP */
128
122
  ) {
129
- ob = new Observer(value, shallow)
123
+ ob = new Observer(value, shallow, ssrMockReactivity)
130
124
  }
131
125
  return ob
132
126
  }
@@ -139,7 +133,8 @@ export function defineReactive(
139
133
  key: string,
140
134
  val?: any,
141
135
  customSetter?: Function | null,
142
- shallow?: boolean
136
+ shallow?: boolean,
137
+ mock?: boolean
143
138
  ) {
144
139
  const dep = new Dep()
145
140
 
@@ -158,7 +153,7 @@ export function defineReactive(
158
153
  val = obj[key]
159
154
  }
160
155
 
161
- let childOb = !shallow && observe(val)
156
+ let childOb = !shallow && observe(val, false, mock)
162
157
  Object.defineProperty(obj, key, {
163
158
  enumerable: true,
164
159
  configurable: true,
@@ -202,7 +197,7 @@ export function defineReactive(
202
197
  } else {
203
198
  val = newVal
204
199
  }
205
- childOb = !shallow && observe(newVal)
200
+ childOb = !shallow && observe(newVal, false, mock)
206
201
  if (__DEV__) {
207
202
  dep.notify({
208
203
  type: TriggerOpTypes.SET,
@@ -241,16 +236,20 @@ export function set(
241
236
  __DEV__ && warn(`Set operation on key "${key}" failed: target is readonly.`)
242
237
  return
243
238
  }
239
+ const ob = (target as any).__ob__
244
240
  if (isArray(target) && isValidArrayIndex(key)) {
245
241
  target.length = Math.max(target.length, key)
246
242
  target.splice(key, 1, val)
243
+ // when mocking for SSR, array methods are not hijacked
244
+ if (ob && !ob.shallow && ob.mock) {
245
+ observe(val, false, true)
246
+ }
247
247
  return val
248
248
  }
249
249
  if (key in target && !(key in Object.prototype)) {
250
250
  target[key] = val
251
251
  return val
252
252
  }
253
- const ob = (target as any).__ob__
254
253
  if ((target as any)._isVue || (ob && ob.vmCount)) {
255
254
  __DEV__ &&
256
255
  warn(
@@ -263,7 +262,7 @@ export function set(
263
262
  target[key] = val
264
263
  return val
265
264
  }
266
- defineReactive(ob.value, key, val)
265
+ defineReactive(ob.value, key, val, undefined, ob.shallow, ob.mock)
267
266
  if (__DEV__) {
268
267
  ob.dep.notify({
269
268
  type: TriggerOpTypes.ADD,
@@ -86,7 +86,8 @@ if (typeof Promise !== 'undefined' && isNative(Promise)) {
86
86
  }
87
87
 
88
88
  export function nextTick(): Promise<void>
89
- export function nextTick(cb: (...args: any[]) => any, ctx?: object): void
89
+ export function nextTick<T>(this: T, cb: (this: T, ...args: any[]) => any): void
90
+ export function nextTick<T>(cb: (this: T, ...args: any[]) => any, ctx: T): void
90
91
  /**
91
92
  * @internal
92
93
  */
@@ -94,7 +94,7 @@ function normalizeDirectives(
94
94
  // $flow-disable-line
95
95
  return res
96
96
  }
97
- let i, dir
97
+ let i: number, dir: VNodeDirective
98
98
  for (i = 0; i < dirs.length; i++) {
99
99
  dir = dirs[i]
100
100
  if (!dir.modifiers) {
@@ -103,7 +103,7 @@ function normalizeDirectives(
103
103
  }
104
104
  res[getRawDirName(dir)] = dir
105
105
  if (vm._setupState && vm._setupState.__sfc) {
106
- dir.def = resolveAsset(vm, '_setupState', 'v-' + dir.name)
106
+ dir.def = dir.def || resolveAsset(vm, '_setupState', 'v-' + dir.name)
107
107
  }
108
108
  dir.def = dir.def || resolveAsset(vm.$options, 'directives', dir.name, true)
109
109
  }
@@ -14,5 +14,7 @@ export const LIFECYCLE_HOOKS = [
14
14
  'activated',
15
15
  'deactivated',
16
16
  'errorCaptured',
17
- 'serverPrefetch'
17
+ 'serverPrefetch',
18
+ 'renderTracked',
19
+ 'renderTriggered'
18
20
  ] as const
@@ -0,0 +1,117 @@
1
+ import { warn, isFunction, isObject } from 'core/util'
2
+
3
+ interface AsyncComponentOptions {
4
+ loader: Function
5
+ loadingComponent?: any
6
+ errorComponent?: any
7
+ delay?: number
8
+ timeout?: number
9
+ suspensible?: boolean
10
+ onError?: (
11
+ error: Error,
12
+ retry: () => void,
13
+ fail: () => void,
14
+ attempts: number
15
+ ) => any
16
+ }
17
+
18
+ type AsyncComponentFactory = () => {
19
+ component: Promise<any>
20
+ loading?: any
21
+ error?: any
22
+ delay?: number
23
+ timeout?: number
24
+ }
25
+
26
+ /**
27
+ * v3-compatible async component API.
28
+ * @internal the type is manually declared in <root>/types/v3-define-async-component.d.ts
29
+ * because it relies on existing manual types
30
+ */
31
+ export function defineAsyncComponent(
32
+ source: (() => any) | AsyncComponentOptions
33
+ ): AsyncComponentFactory {
34
+ if (isFunction(source)) {
35
+ source = { loader: source } as AsyncComponentOptions
36
+ }
37
+
38
+ const {
39
+ loader,
40
+ loadingComponent,
41
+ errorComponent,
42
+ delay = 200,
43
+ timeout, // undefined = never times out
44
+ suspensible = false, // in Vue 3 default is true
45
+ onError: userOnError
46
+ } = source
47
+
48
+ if (__DEV__ && suspensible) {
49
+ warn(
50
+ `The suspensiblbe option for async components is not supported in Vue2. It is ignored.`
51
+ )
52
+ }
53
+
54
+ let pendingRequest: Promise<any> | null = null
55
+
56
+ let retries = 0
57
+ const retry = () => {
58
+ retries++
59
+ pendingRequest = null
60
+ return load()
61
+ }
62
+
63
+ const load = (): Promise<any> => {
64
+ let thisRequest: Promise<any>
65
+ return (
66
+ pendingRequest ||
67
+ (thisRequest = pendingRequest =
68
+ loader()
69
+ .catch(err => {
70
+ err = err instanceof Error ? err : new Error(String(err))
71
+ if (userOnError) {
72
+ return new Promise((resolve, reject) => {
73
+ const userRetry = () => resolve(retry())
74
+ const userFail = () => reject(err)
75
+ userOnError(err, userRetry, userFail, retries + 1)
76
+ })
77
+ } else {
78
+ throw err
79
+ }
80
+ })
81
+ .then((comp: any) => {
82
+ if (thisRequest !== pendingRequest && pendingRequest) {
83
+ return pendingRequest
84
+ }
85
+ if (__DEV__ && !comp) {
86
+ warn(
87
+ `Async component loader resolved to undefined. ` +
88
+ `If you are using retry(), make sure to return its return value.`
89
+ )
90
+ }
91
+ // interop module default
92
+ if (
93
+ comp &&
94
+ (comp.__esModule || comp[Symbol.toStringTag] === 'Module')
95
+ ) {
96
+ comp = comp.default
97
+ }
98
+ if (__DEV__ && comp && !isObject(comp) && !isFunction(comp)) {
99
+ throw new Error(`Invalid async component load result: ${comp}`)
100
+ }
101
+ return comp
102
+ }))
103
+ )
104
+ }
105
+
106
+ return () => {
107
+ const component = load()
108
+
109
+ return {
110
+ component,
111
+ delay,
112
+ timeout,
113
+ error: errorComponent,
114
+ loading: loadingComponent
115
+ }
116
+ }
117
+ }