vue 2.7.2 → 2.7.5

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 (41) hide show
  1. package/dist/vue.common.dev.js +3395 -3308
  2. package/dist/vue.common.prod.js +3 -3
  3. package/dist/vue.esm.browser.js +3351 -3265
  4. package/dist/vue.esm.browser.min.js +3 -3
  5. package/dist/vue.esm.js +3628 -3539
  6. package/dist/vue.js +3408 -3318
  7. package/dist/vue.min.js +3 -3
  8. package/dist/vue.runtime.common.dev.js +2788 -2701
  9. package/dist/vue.runtime.common.prod.js +3 -3
  10. package/dist/vue.runtime.esm.js +2737 -2648
  11. package/dist/vue.runtime.js +2810 -2720
  12. package/dist/vue.runtime.min.js +3 -3
  13. package/dist/vue.runtime.mjs +73 -8604
  14. package/package.json +2 -2
  15. package/packages/compiler-sfc/dist/compiler-sfc.js +1004 -1000
  16. package/packages/compiler-sfc/package.json +1 -1
  17. package/packages/compiler-sfc/src/parseComponent.ts +7 -4
  18. package/packages/compiler-sfc/test/parseComponent.spec.ts +6 -7
  19. package/src/core/components/keep-alive.ts +5 -4
  20. package/src/core/global-api/extend.ts +3 -1
  21. package/src/core/instance/init.ts +1 -1
  22. package/src/core/instance/lifecycle.ts +8 -3
  23. package/src/core/instance/render-helpers/render-static.ts +1 -1
  24. package/src/core/observer/index.ts +54 -55
  25. package/src/core/observer/traverse.ts +3 -0
  26. package/src/core/util/debug.ts +2 -1
  27. package/src/core/vdom/create-component.ts +5 -1
  28. package/src/platforms/web/runtime/components/transition-group.ts +2 -1
  29. package/src/shared/constants.ts +3 -1
  30. package/src/v3/apiAsyncComponent.ts +117 -0
  31. package/src/v3/apiWatch.ts +6 -8
  32. package/src/v3/index.ts +6 -0
  33. package/src/v3/reactivity/reactive.ts +13 -2
  34. package/src/v3/reactivity/ref.ts +17 -4
  35. package/types/jsx.d.ts +6 -0
  36. package/types/options.d.ts +5 -3
  37. package/types/v3-component-public-instance.d.ts +36 -32
  38. package/types/v3-define-async-component.d.ts +26 -0
  39. package/types/v3-define-component.d.ts +25 -1
  40. package/types/v3-generated.d.ts +23 -0
  41. package/types/vue.d.ts +27 -12
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vue/compiler-sfc",
3
- "version": "2.7.2",
3
+ "version": "2.7.5",
4
4
  "description": "compiler-sfc for Vue 2",
5
5
  "main": "dist/compiler-sfc.js",
6
6
  "types": "dist/compiler-sfc.d.ts",
@@ -10,7 +10,6 @@ export const DEFAULT_FILENAME = 'anonymous.vue'
10
10
  const splitRE = /\r?\n/g
11
11
  const replaceRE = /./g
12
12
  const isSpecialTag = makeMap('script,style,template', true)
13
- const isNeedIndentLang = makeMap('pug,jade')
14
13
 
15
14
  export interface SFCCustomBlock {
16
15
  type: string
@@ -179,9 +178,13 @@ export function parseComponent(
179
178
  currentBlock.end = start
180
179
  let text = source.slice(currentBlock.start, currentBlock.end)
181
180
  if (
182
- options.deindent ||
183
- // certain langs like pug are indent sensitive, preserve old behavior
184
- (currentBlock.lang && isNeedIndentLang(currentBlock.lang))
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
+ ))
185
188
  ) {
186
189
  text = deindent(text)
187
190
  }
@@ -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
 
@@ -3,6 +3,7 @@ import { getFirstComponentChild } from 'core/vdom/helpers/index'
3
3
  import type VNode from 'core/vdom/vnode'
4
4
  import type { VNodeComponentOptions } from 'types/vnode'
5
5
  import type { Component } from 'types/component'
6
+ import { getComponentName } from '../vdom/create-component'
6
7
 
7
8
  type CacheEntry = {
8
9
  name?: string
@@ -12,8 +13,8 @@ type CacheEntry = {
12
13
 
13
14
  type CacheEntryMap = Record<string, CacheEntry | null>
14
15
 
15
- function getComponentName(opts?: VNodeComponentOptions): string | null {
16
- return opts && (opts.Ctor.options.name || opts.tag)
16
+ function _getComponentName(opts?: VNodeComponentOptions): string | null {
17
+ return opts && (getComponentName(opts.Ctor.options as any) || opts.tag)
17
18
  }
18
19
 
19
20
  function matches(
@@ -81,7 +82,7 @@ export default {
81
82
  if (vnodeToCache) {
82
83
  const { tag, componentInstance, componentOptions } = vnodeToCache
83
84
  cache[keyToCache] = {
84
- name: getComponentName(componentOptions),
85
+ name: _getComponentName(componentOptions),
85
86
  tag,
86
87
  componentInstance
87
88
  }
@@ -126,7 +127,7 @@ export default {
126
127
  const componentOptions = vnode && vnode.componentOptions
127
128
  if (componentOptions) {
128
129
  // check pattern
129
- const name = getComponentName(componentOptions)
130
+ const name = _getComponentName(componentOptions)
130
131
  const { include, exclude } = this
131
132
  if (
132
133
  // not included
@@ -3,6 +3,7 @@ import type { Component } from 'types/component'
3
3
  import type { GlobalAPI } from 'types/global-api'
4
4
  import { defineComputed, proxy } from '../instance/state'
5
5
  import { extend, mergeOptions, validateComponentName } from '../util/index'
6
+ import { getComponentName } from '../vdom/create-component'
6
7
 
7
8
  export function initExtend(Vue: GlobalAPI) {
8
9
  /**
@@ -25,7 +26,8 @@ export function initExtend(Vue: GlobalAPI) {
25
26
  return cachedCtors[SuperId]
26
27
  }
27
28
 
28
- const name = extendOptions.name || Super.options.name
29
+ const name =
30
+ getComponentName(extendOptions) || getComponentName(Super.options)
29
31
  if (__DEV__ && name) {
30
32
  validateComponentName(name)
31
33
  }
@@ -58,7 +58,7 @@ export function initMixin(Vue: typeof Component) {
58
58
  initLifecycle(vm)
59
59
  initEvents(vm)
60
60
  initRender(vm)
61
- callHook(vm, 'beforeCreate')
61
+ callHook(vm, 'beforeCreate', undefined, false /* setContext */)
62
62
  initInjections(vm) // resolve injections before data/props
63
63
  initState(vm)
64
64
  initProvide(vm) // resolve provide after data/props
@@ -375,11 +375,16 @@ export function deactivateChildComponent(vm: Component, direct?: boolean) {
375
375
  }
376
376
  }
377
377
 
378
- export function callHook(vm: Component, hook: string, args?: any[]) {
378
+ export function callHook(
379
+ vm: Component,
380
+ hook: string,
381
+ args?: any[],
382
+ setContext = true
383
+ ) {
379
384
  // #7573 disable dep collection when invoking lifecycle hooks
380
385
  pushTarget()
381
386
  const prev = currentInstance
382
- setCurrentInstance(vm)
387
+ setContext && setCurrentInstance(vm)
383
388
  const handlers = vm.$options[hook]
384
389
  const info = `${hook} hook`
385
390
  if (handlers) {
@@ -390,6 +395,6 @@ export function callHook(vm: Component, hook: string, args?: any[]) {
390
395
  if (vm._hasHookEvent) {
391
396
  vm.$emit('hook:' + hook)
392
397
  }
393
- setCurrentInstance(prev)
398
+ setContext && setCurrentInstance(prev)
394
399
  popTarget()
395
400
  }
@@ -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,
@@ -1,6 +1,7 @@
1
1
  import { _Set as Set, isObject, isArray } from '../util/index'
2
2
  import type { SimpleSet } from '../util/index'
3
3
  import VNode from '../vdom/vnode'
4
+ import { isRef } from '../../v3'
4
5
 
5
6
  const seenObjects = new Set()
6
7
 
@@ -35,6 +36,8 @@ function _traverse(val: any, seen: SimpleSet) {
35
36
  if (isA) {
36
37
  i = val.length
37
38
  while (i--) _traverse(val[i], seen)
39
+ } else if (isRef(val)) {
40
+ _traverse(val.value, seen)
38
41
  } else {
39
42
  keys = Object.keys(val)
40
43
  i = keys.length
@@ -2,6 +2,7 @@ import config from '../config'
2
2
  import { noop, isArray, isFunction } from 'shared/util'
3
3
  import type { Component } from 'types/component'
4
4
  import { currentInstance } from 'v3/currentInstance'
5
+ import { getComponentName } from '../vdom/create-component'
5
6
 
6
7
  export let warn: (msg: string, vm?: Component | null) => void = noop
7
8
  export let tip = noop
@@ -40,7 +41,7 @@ if (__DEV__) {
40
41
  : vm._isVue
41
42
  ? vm.$options || (vm.constructor as any).options
42
43
  : vm
43
- let name = options.name || options._componentTag
44
+ let name = getComponentName(options)
44
45
  const file = options.__file
45
46
  if (!name && file) {
46
47
  const match = file.match(/([^/\\]+)\.vue$/)
@@ -28,6 +28,10 @@ import type {
28
28
  import type { Component } from 'types/component'
29
29
  import type { ComponentOptions, InternalComponentOptions } from 'types/options'
30
30
 
31
+ export function getComponentName(options: ComponentOptions) {
32
+ return options.name || options.__name || options._componentTag
33
+ }
34
+
31
35
  // inline hooks to be invoked on component VNodes during patch
32
36
  const componentVNodeHooks = {
33
37
  init(vnode: VNodeWithData, hydrating: boolean): boolean | void {
@@ -188,7 +192,7 @@ export function createComponent(
188
192
 
189
193
  // return a placeholder vnode
190
194
  // @ts-expect-error
191
- const name = Ctor.options.name || tag
195
+ const name = getComponentName(Ctor.options) || tag
192
196
  const vnode = new VNode(
193
197
  // @ts-expect-error
194
198
  `vue-component-${Ctor.cid}${name ? `-${name}` : ''}`,
@@ -23,6 +23,7 @@ import {
23
23
  } from 'web/runtime/transition-util'
24
24
  import VNode from 'core/vdom/vnode'
25
25
  import { VNodeWithData } from 'types/vnode'
26
+ import { getComponentName } from 'core/vdom/create-component'
26
27
 
27
28
  const props = extend(
28
29
  {
@@ -72,7 +73,7 @@ export default {
72
73
  } else if (__DEV__) {
73
74
  const opts = c.componentOptions
74
75
  const name: string = opts
75
- ? opts.Ctor.options.name || opts.tag || ''
76
+ ? getComponentName(opts.Ctor.options as any) || opts.tag || ''
76
77
  : c.tag
77
78
  warn(`<transition-group> children must be keyed: <${name}>`)
78
79
  }
@@ -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
+ }
@@ -196,12 +196,10 @@ function doWatch(
196
196
  getter = () => source.value
197
197
  forceTrigger = isShallow(source)
198
198
  } else if (isReactive(source)) {
199
- getter = isArray(source)
200
- ? () => {
201
- ;(source as any).__ob__.dep.depend()
202
- return source
203
- }
204
- : () => source
199
+ getter = () => {
200
+ ;(source as any).__ob__.dep.depend()
201
+ return source
202
+ }
205
203
  deep = true
206
204
  } else if (isArray(source)) {
207
205
  isMultiSource = true
@@ -320,8 +318,8 @@ function doWatch(
320
318
  } else {
321
319
  // pre
322
320
  watcher.update = () => {
323
- if (instance && instance === currentInstance) {
324
- // pre-watcher triggered inside setup()
321
+ if (instance && instance === currentInstance && !instance._isMounted) {
322
+ // pre-watcher triggered before
325
323
  const buffer = instance._preWatchers || (instance._preWatchers = [])
326
324
  if (buffer.indexOf(watcher) < 0) buffer.push(watcher)
327
325
  } else {
package/src/v3/index.ts CHANGED
@@ -1,3 +1,7 @@
1
+ /**
2
+ * Note: also update dist/vue.runtime.mjs when adding new exports to this file.
3
+ */
4
+
1
5
  export const version: string = '__VERSION__'
2
6
 
3
7
  export {
@@ -87,4 +91,6 @@ export function defineComponent(options: any) {
87
91
  return options
88
92
  }
89
93
 
94
+ export { defineAsyncComponent } from './apiAsyncComponent'
95
+
90
96
  export * from './apiLifecycle'
@@ -1,5 +1,12 @@
1
1
  import { observe, Observer } from 'core/observer'
2
- import { def, isArray, isPrimitive, warn, toRawType } from 'core/util'
2
+ import {
3
+ def,
4
+ isArray,
5
+ isPrimitive,
6
+ warn,
7
+ toRawType,
8
+ isServerRendering
9
+ } from 'core/util'
3
10
  import type { Ref, UnwrapRefSimple, RawSymbol } from './ref'
4
11
 
5
12
  export const enum ReactiveFlags {
@@ -67,7 +74,11 @@ function makeReactive(target: any, shallow: boolean) {
67
74
  )
68
75
  }
69
76
  }
70
- const ob = observe(target, shallow)
77
+ const ob = observe(
78
+ target,
79
+ shallow,
80
+ isServerRendering() /* ssr mock reactivity */
81
+ )
71
82
  if (__DEV__ && !ob) {
72
83
  if (target == null || isPrimitive(target)) {
73
84
  warn(`value cannot be made reactive: ${String(target)}`)