vue 2.7.3 → 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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vue",
3
- "version": "2.7.3",
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.3",
63
+ "@vue/compiler-sfc": "2.7.4",
64
64
  "csstype": "^3.1.0"
65
65
  },
66
66
  "devDependencies": {
@@ -646,7 +646,6 @@ const DEFAULT_FILENAME = 'anonymous.vue';
646
646
  const splitRE$1 = /\r?\n/g;
647
647
  const replaceRE = /./g;
648
648
  const isSpecialTag = makeMap('script,style,template', true);
649
- const isNeedIndentLang = makeMap('pug,jade');
650
649
  /**
651
650
  * Parse a single-file component (*.vue) file into an SFC Descriptor Object.
652
651
  */
@@ -741,9 +740,11 @@ function parseComponent(source, options = {}) {
741
740
  if (depth === 1 && currentBlock) {
742
741
  currentBlock.end = start;
743
742
  let text = source.slice(currentBlock.start, currentBlock.end);
744
- if (options.deindent ||
745
- // certain langs like pug are indent sensitive, preserve old behavior
746
- (currentBlock.lang && isNeedIndentLang(currentBlock.lang))) {
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')))) {
747
748
  text = deIndent(text);
748
749
  }
749
750
  // pad content so that linters and pre-processors can output correct
@@ -4362,7 +4363,7 @@ function renderStatic(index, isInFor) {
4362
4363
  return tree;
4363
4364
  }
4364
4365
  // otherwise, render a fresh tree.
4365
- 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
4366
4367
  );
4367
4368
  markStatic$1(tree, `__static__${index}`, false);
4368
4369
  return tree;
@@ -5369,7 +5370,7 @@ function set(target, key, val) {
5369
5370
  target.length = Math.max(target.length, key);
5370
5371
  target.splice(key, 1, val);
5371
5372
  // when mocking for SSR, array methods are not hijacked
5372
- if (!ob.shallow && ob.mock) {
5373
+ if (ob && !ob.shallow && ob.mock) {
5373
5374
  observe(val, false, true);
5374
5375
  }
5375
5376
  return val;
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vue/compiler-sfc",
3
- "version": "2.7.3",
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",
@@ -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
 
@@ -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)
@@ -241,7 +241,7 @@ export function set(
241
241
  target.length = Math.max(target.length, key)
242
242
  target.splice(key, 1, val)
243
243
  // when mocking for SSR, array methods are not hijacked
244
- if (!ob.shallow && ob.mock) {
244
+ if (ob && !ob.shallow && ob.mock) {
245
245
  observe(val, false, true)
246
246
  }
247
247
  return val
@@ -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
+ }
@@ -320,8 +320,8 @@ function doWatch(
320
320
  } else {
321
321
  // pre
322
322
  watcher.update = () => {
323
- if (instance && instance === currentInstance) {
324
- // pre-watcher triggered inside setup()
323
+ if (instance && instance === currentInstance && !instance._isMounted) {
324
+ // pre-watcher triggered before
325
325
  const buffer = instance._preWatchers || (instance._preWatchers = [])
326
326
  if (buffer.indexOf(watcher) < 0) buffer.push(watcher)
327
327
  } 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'
@@ -20,7 +20,7 @@ export type Component<
20
20
  | typeof Vue
21
21
  | FunctionalComponentOptions<Props>
22
22
  | ComponentOptions<never, Data, Methods, Computed, Props, SetupBindings>
23
- | DefineComponent<any, any, any, any, any>
23
+ | DefineComponent<any, any, any, any, any, any, any, any, any, any, any>
24
24
 
25
25
  type EsModule<T> = T | { default: T }
26
26
 
@@ -201,9 +201,9 @@ export interface ComponentOptions<
201
201
  directives?: { [key: string]: DirectiveFunction | DirectiveOptions }
202
202
  components?: {
203
203
  [key: string]:
204
- | Component<any, any, any, any>
204
+ | {}
205
+ | Component<any, any, any, any, any>
205
206
  | AsyncComponent<any, any, any, any>
206
- | DefineComponent<any, any, any, any, any, any, any, any, any, any>
207
207
  }
208
208
  transitions?: { [key: string]: object }
209
209
  filters?: { [key: string]: Function }
@@ -1,15 +1,11 @@
1
- import { ExtractDefaultPropTypes, ExtractPropTypes } from './v3-component-props'
2
1
  import {
3
2
  DebuggerEvent,
4
- nextTick,
5
3
  ShallowUnwrapRef,
6
- UnwrapNestedRefs,
7
- WatchOptions,
8
- WatchStopHandle
4
+ UnwrapNestedRefs
9
5
  } from './v3-generated'
10
- import { Data, UnionToIntersection } from './common'
6
+ import { UnionToIntersection } from './common'
11
7
 
12
- import { VueConstructor } from './vue'
8
+ import { Vue, Vue2Instance, VueConstructor } from './vue'
13
9
  import {
14
10
  ComputedOptions,
15
11
  MethodOptions,
@@ -18,6 +14,7 @@ import {
18
14
  ComponentOptionsBase
19
15
  } from './v3-component-options'
20
16
  import { EmitFn, EmitsOptions, Slots } from './v3-setup-context'
17
+ import { VNode } from './vnode'
21
18
 
22
19
  /**
23
20
  * Custom properties added to component instances in any way and can be accessed through `this`
@@ -152,36 +149,43 @@ export type ComponentPublicInstance<
152
149
  any,
153
150
  any
154
151
  >
155
- > = {
156
- // $: ComponentInternalInstance
157
- $data: D
158
- $props: Readonly<
159
- MakeDefaultsOptional extends true
160
- ? Partial<Defaults> & Omit<P & PublicProps, keyof Defaults>
161
- : P & PublicProps
162
- >
163
- $attrs: Data
164
- $refs: Data
165
- $slots: Slots
166
- $root: ComponentPublicInstance | null
167
- $parent: ComponentPublicInstance | null
168
- $emit: EmitFn<E>
169
- $el: any
170
- $options: Options & MergedComponentOptionsOverride
171
- $forceUpdate: () => void
172
- $nextTick: typeof nextTick
173
- $watch(
174
- source: string | Function,
175
- cb: Function,
176
- options?: WatchOptions
177
- ): WatchStopHandle
178
- } & Readonly<P> &
152
+ > = Vue3Instance<
153
+ D,
154
+ P,
155
+ PublicProps,
156
+ E,
157
+ Defaults,
158
+ MakeDefaultsOptional,
159
+ Options
160
+ > &
161
+ Readonly<P> &
179
162
  ShallowUnwrapRef<B> &
180
163
  UnwrapNestedRefs<D> &
181
164
  ExtractComputedReturns<C> &
182
165
  M &
183
166
  ComponentCustomProperties
184
167
 
168
+ interface Vue3Instance<
169
+ D,
170
+ P,
171
+ PublicProps,
172
+ E,
173
+ Defaults,
174
+ MakeDefaultsOptional,
175
+ Options
176
+ > extends Vue2Instance {
177
+ $data: D
178
+ readonly $props: Readonly<
179
+ MakeDefaultsOptional extends true
180
+ ? Partial<Defaults> & Omit<P & PublicProps, keyof Defaults>
181
+ : P & PublicProps
182
+ >
183
+ readonly $root: ComponentPublicInstance | null
184
+ readonly $parent: ComponentPublicInstance | null
185
+ readonly $emit: EmitFn<E>
186
+ readonly $options: Options & MergedComponentOptionsOverride
187
+ }
188
+
185
189
  type MergedHook<T = () => void> = T | T[]
186
190
 
187
191
  export type MergedComponentOptionsOverride = {
@@ -0,0 +1,26 @@
1
+ import { AsyncComponent, Component } from './options'
2
+
3
+ export type AsyncComponentResolveResult<T = Component> = T | { default: T } // es modules
4
+
5
+ export type AsyncComponentLoader<T = any> = () => Promise<
6
+ AsyncComponentResolveResult<T>
7
+ >
8
+
9
+ export interface AsyncComponentOptions {
10
+ loader: AsyncComponentLoader
11
+ loadingComponent?: Component
12
+ errorComponent?: Component
13
+ delay?: number
14
+ timeout?: number
15
+ // suspensible?: boolean
16
+ onError?: (
17
+ error: Error,
18
+ retry: () => void,
19
+ fail: () => void,
20
+ attempts: number
21
+ ) => any
22
+ }
23
+
24
+ export function defineAsyncComponent(
25
+ source: AsyncComponentLoader | AsyncComponentOptions
26
+ ): AsyncComponent
@@ -1,4 +1,3 @@
1
- import { Component } from '..'
2
1
  import {
3
2
  ComponentPropsOptions,
4
3
  ExtractDefaultPropTypes,
@@ -19,6 +18,7 @@ import {
19
18
  } from './v3-component-public-instance'
20
19
  import { Data, HasDefined } from './common'
21
20
  import { EmitsOptions } from './v3-setup-context'
21
+ import { CreateElement, RenderContext } from './umd'
22
22
 
23
23
  type DefineComponent<
24
24
  PropsOrPropOptions = {},
@@ -67,6 +67,30 @@ type DefineComponent<
67
67
  props: PropsOrPropOptions
68
68
  }
69
69
 
70
+ /**
71
+ * overload 0.0: functional component with array props
72
+ */
73
+ export function defineComponent<
74
+ PropNames extends string,
75
+ Props = Readonly<{ [key in PropNames]?: any }>
76
+ >(options: {
77
+ functional: true
78
+ props?: PropNames[]
79
+ render?: (h: CreateElement, context: RenderContext<Props>) => any
80
+ }): DefineComponent<Props>
81
+
82
+ /**
83
+ * overload 0.1: functional component with object props
84
+ */
85
+ export function defineComponent<
86
+ PropsOptions extends ComponentPropsOptions = ComponentPropsOptions,
87
+ Props = ExtractPropTypes<PropsOptions>
88
+ >(options: {
89
+ functional: true
90
+ props?: PropsOptions
91
+ render?: (h: CreateElement, context: RenderContext<Props>) => any
92
+ }): DefineComponent<PropsOptions>
93
+
70
94
  /**
71
95
  * overload 1: object format with no props
72
96
  */
@@ -2,6 +2,24 @@ declare type ASTModifiers = {
2
2
  [key: string]: boolean;
3
3
  };
4
4
 
5
+ declare type AsyncComponentFactory = () => {
6
+ component: Promise<any>;
7
+ loading?: any;
8
+ error?: any;
9
+ delay?: number;
10
+ timeout?: number;
11
+ };
12
+
13
+ declare interface AsyncComponentOptions {
14
+ loader: Function;
15
+ loadingComponent?: any;
16
+ errorComponent?: any;
17
+ delay?: number;
18
+ timeout?: number;
19
+ suspensible?: boolean;
20
+ onError?: (error: Error, retry: () => void, fail: () => void, attempts: number) => any;
21
+ }
22
+
5
23
  declare type BaseTypes = string | number | boolean;
6
24
 
7
25
  declare type Builtin = Primitive | Function | Date | Error | RegExp;
@@ -57,6 +75,8 @@ export declare type DeepReadonly<T> = T extends Builtin ? T : T extends Map<infe
57
75
  readonly [K in keyof T]: DeepReadonly<T[K]>;
58
76
  } : Readonly<T>;
59
77
 
78
+ /* Excluded from this release type: defineAsyncComponent */
79
+
60
80
  /* Excluded from this release type: defineComponent */
61
81
 
62
82
  /**
@@ -346,6 +366,9 @@ export declare function useCssVars(getter: (vm: Record<string, any>, setupProxy:
346
366
 
347
367
  /* Excluded from this release type: useSlots */
348
368
 
369
+ /**
370
+ * Note: also update dist/vue.runtime.mjs when adding new exports to this file.
371
+ */
349
372
  export declare const version: string;
350
373
 
351
374
  /* Excluded from this release type: VNode */
package/types/vue.d.ts CHANGED
@@ -3,8 +3,6 @@ import {
3
3
  AsyncComponent,
4
4
  ComponentOptions,
5
5
  FunctionalComponentOptions,
6
- WatchOptionsWithHandler,
7
- WatchHandler,
8
6
  DirectiveOptions,
9
7
  DirectiveFunction,
10
8
  RecordPropsDefinition,
@@ -14,6 +12,8 @@ import {
14
12
  } from './options'
15
13
  import { VNode, VNodeData, VNodeChildren, NormalizedScopedSlot } from './vnode'
16
14
  import { PluginFunction, PluginObject } from './plugin'
15
+ import { DefineComponent } from './v3-define-component'
16
+ import { nextTick } from './v3-generated'
17
17
 
18
18
  export interface CreateElement {
19
19
  (
@@ -35,20 +35,25 @@ export interface CreateElement {
35
35
  ): VNode
36
36
  }
37
37
 
38
- export interface Vue {
39
- readonly $el: Element
40
- readonly $options: ComponentOptions<Vue>
38
+ export interface Vue extends Vue2Instance {
39
+ readonly $data: Record<string, any>
40
+ readonly $props: Record<string, any>
41
41
  readonly $parent: Vue
42
42
  readonly $root: Vue
43
43
  readonly $children: Vue[]
44
+ readonly $options: ComponentOptions<Vue>
45
+ $emit(event: string, ...args: any[]): this
46
+ }
47
+
48
+ export interface Vue2Instance {
49
+ readonly $el: Element
44
50
  readonly $refs: {
45
51
  [key: string]: Vue | Element | (Vue | Element)[] | undefined
46
52
  }
47
53
  readonly $slots: { [key: string]: VNode[] | undefined }
48
54
  readonly $scopedSlots: { [key: string]: NormalizedScopedSlot | undefined }
49
55
  readonly $isServer: boolean
50
- readonly $data: Record<string, any>
51
- readonly $props: Record<string, any>
56
+
52
57
  readonly $ssrContext: any
53
58
  readonly $vnode: VNode
54
59
  readonly $attrs: Record<string, string>
@@ -72,9 +77,7 @@ export interface Vue {
72
77
  $on(event: string | string[], callback: Function): this
73
78
  $once(event: string | string[], callback: Function): this
74
79
  $off(event?: string | string[], callback?: Function): this
75
- $emit(event: string, ...args: any[]): this
76
- $nextTick(callback: (this: this) => void): void
77
- $nextTick(): Promise<void>
80
+ $nextTick: typeof nextTick
78
81
  $createElement: CreateElement
79
82
  }
80
83
 
@@ -313,6 +316,10 @@ export interface VueConstructor<V extends Vue = Vue> {
313
316
  id: string,
314
317
  definition?: ComponentOptions<V>
315
318
  ): ExtendedVue<V, {}, {}, {}, {}, {}>
319
+ component<T extends DefineComponent<any, any, any, any, any, any, any, any>>(
320
+ id: string,
321
+ definition?: T
322
+ ): T
316
323
 
317
324
  use<T>(
318
325
  plugin: PluginObject<T> | PluginFunction<T>,