vue 2.7.0 → 2.7.1

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.
@@ -329,7 +329,7 @@ function hasChanged(x, y) {
329
329
  return x === 0 && 1 / x !== 1 / y;
330
330
  }
331
331
  else {
332
- return x === x && y === y;
332
+ return x === x || y === y;
333
333
  }
334
334
  }
335
335
 
@@ -5319,7 +5319,7 @@ function defineReactive(obj, key, val, customSetter, shallow) {
5319
5319
  }
5320
5320
  }
5321
5321
  }
5322
- return isRef(value) ? value.value : value;
5322
+ return isRef(value) && !shallow ? value.value : value;
5323
5323
  },
5324
5324
  set: function reactiveSetter(newVal) {
5325
5325
  const value = getter ? getter.call(obj) : val;
@@ -8360,18 +8360,14 @@ function compileScript(sfc, options = { id: '' }) {
8360
8360
  function error(msg, node, end = node.end + startOffset) {
8361
8361
  throw new Error(`[@vue/compiler-sfc] ${msg}\n\n${filename}\n${generateCodeFrame(source, node.start + startOffset, end)}`);
8362
8362
  }
8363
- function registerUserImport(source, local, imported, isType, isFromSetup, needTemplateUsageCheck) {
8363
+ function registerUserImport(source, local, imported, isType, isFromSetup) {
8364
8364
  if (source === 'vue' && imported) {
8365
8365
  userImportAlias[imported] = local;
8366
8366
  }
8367
8367
  // template usage check is only needed in non-inline mode, so we can skip
8368
8368
  // the work if inlineTemplate is true.
8369
- let isUsedInTemplate = needTemplateUsageCheck;
8370
- if (needTemplateUsageCheck &&
8371
- isTS &&
8372
- sfc.template &&
8373
- !sfc.template.src &&
8374
- !sfc.template.lang) {
8369
+ let isUsedInTemplate = true;
8370
+ if (isTS && sfc.template && !sfc.template.src && !sfc.template.lang) {
8375
8371
  isUsedInTemplate = isImportUsed(local, sfc);
8376
8372
  }
8377
8373
  userImports[local] = {
@@ -8622,7 +8618,7 @@ function compileScript(sfc, options = { id: '' }) {
8622
8618
  specifier.imported.name;
8623
8619
  registerUserImport(node.source.value, specifier.local.name, imported, node.importKind === 'type' ||
8624
8620
  (specifier.type === 'ImportSpecifier' &&
8625
- specifier.importKind === 'type'), false, true);
8621
+ specifier.importKind === 'type'), false);
8626
8622
  }
8627
8623
  }
8628
8624
  else if (node.type === 'ExportDefaultDeclaration') {
@@ -8791,7 +8787,7 @@ function compileScript(sfc, options = { id: '' }) {
8791
8787
  else {
8792
8788
  registerUserImport(source, local, imported, node.importKind === 'type' ||
8793
8789
  (specifier.type === 'ImportSpecifier' &&
8794
- specifier.importKind === 'type'), true, true);
8790
+ specifier.importKind === 'type'), true);
8795
8791
  }
8796
8792
  }
8797
8793
  if (node.specifiers.length && removed === node.specifiers.length) {
@@ -9526,7 +9522,11 @@ function resolveTemplateUsageCheckString(sfc) {
9526
9522
  for (let i = 0; i < attrs.length; i++) {
9527
9523
  const { name, value } = attrs[i];
9528
9524
  if (dirRE.test(name)) {
9529
- const baseName = name.replace(dirRE, '');
9525
+ const baseName = onRE.test(name)
9526
+ ? 'on'
9527
+ : bindRE.test(name)
9528
+ ? 'bind'
9529
+ : name.replace(dirRE, '');
9530
9530
  if (!isBuiltInDir$1(baseName)) {
9531
9531
  code += `,v${capitalize(camelize(baseName))}`;
9532
9532
  }
@@ -9552,6 +9552,9 @@ function processExp(exp, dir) {
9552
9552
  if (dir === 'slot') {
9553
9553
  exp = `(${exp})=>{}`;
9554
9554
  }
9555
+ else if (dir === 'on') {
9556
+ exp = `()=>{${exp}}`;
9557
+ }
9555
9558
  else if (dir === 'for') {
9556
9559
  const inMatch = exp.match(forAliasRE);
9557
9560
  if (inMatch) {
@@ -9807,7 +9810,7 @@ function transform(node, transformAssetUrlsOptions) {
9807
9810
  return;
9808
9811
  }
9809
9812
  const imageCandidates = value
9810
- .substr(1, value.length - 2)
9813
+ .slice(1, -1)
9811
9814
  .split(',')
9812
9815
  .map(s => {
9813
9816
  // The attribute value arrives here with all whitespace, except
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vue/compiler-sfc",
3
- "version": "2.7.0",
3
+ "version": "2.7.1",
4
4
  "description": "compiler-sfc for Vue 2",
5
5
  "main": "dist/compiler-sfc.js",
6
6
  "types": "dist/compiler-sfc.d.ts",
@@ -39,7 +39,7 @@ import { walk } from 'estree-walker'
39
39
  import { RawSourceMap } from 'source-map'
40
40
  import { warnOnce } from './warn'
41
41
  import { isReservedTag } from 'web/util'
42
- import { dirRE } from 'compiler/parser'
42
+ import { bindRE, dirRE, onRE } from 'compiler/parser'
43
43
  import { parseText } from 'compiler/parser/text-parser'
44
44
  import { DEFAULT_FILENAME } from './parseComponent'
45
45
  import {
@@ -278,8 +278,7 @@ export function compileScript(
278
278
  local: string,
279
279
  imported: string | false,
280
280
  isType: boolean,
281
- isFromSetup: boolean,
282
- needTemplateUsageCheck: boolean
281
+ isFromSetup: boolean
283
282
  ) {
284
283
  if (source === 'vue' && imported) {
285
284
  userImportAlias[imported] = local
@@ -287,14 +286,8 @@ export function compileScript(
287
286
 
288
287
  // template usage check is only needed in non-inline mode, so we can skip
289
288
  // the work if inlineTemplate is true.
290
- let isUsedInTemplate = needTemplateUsageCheck
291
- if (
292
- needTemplateUsageCheck &&
293
- isTS &&
294
- sfc.template &&
295
- !sfc.template.src &&
296
- !sfc.template.lang
297
- ) {
289
+ let isUsedInTemplate = true
290
+ if (isTS && sfc.template && !sfc.template.src && !sfc.template.lang) {
298
291
  isUsedInTemplate = isImportUsed(local, sfc)
299
292
  }
300
293
 
@@ -658,8 +651,7 @@ export function compileScript(
658
651
  node.importKind === 'type' ||
659
652
  (specifier.type === 'ImportSpecifier' &&
660
653
  specifier.importKind === 'type'),
661
- false,
662
- true
654
+ false
663
655
  )
664
656
  }
665
657
  } else if (node.type === 'ExportDefaultDeclaration') {
@@ -872,7 +864,6 @@ export function compileScript(
872
864
  node.importKind === 'type' ||
873
865
  (specifier.type === 'ImportSpecifier' &&
874
866
  specifier.importKind === 'type'),
875
- true,
876
867
  true
877
868
  )
878
869
  }
@@ -1809,7 +1800,11 @@ function resolveTemplateUsageCheckString(sfc: SFCDescriptor) {
1809
1800
  for (let i = 0; i < attrs.length; i++) {
1810
1801
  const { name, value } = attrs[i]
1811
1802
  if (dirRE.test(name)) {
1812
- const baseName = name.replace(dirRE, '')
1803
+ const baseName = onRE.test(name)
1804
+ ? 'on'
1805
+ : bindRE.test(name)
1806
+ ? 'bind'
1807
+ : name.replace(dirRE, '')
1813
1808
  if (!isBuiltInDir(baseName)) {
1814
1809
  code += `,v${capitalize(camelize(baseName))}`
1815
1810
  }
@@ -1838,6 +1833,8 @@ function processExp(exp: string, dir?: string): string {
1838
1833
  if (/ as\s+\w|<.*>|:/.test(exp)) {
1839
1834
  if (dir === 'slot') {
1840
1835
  exp = `(${exp})=>{}`
1836
+ } else if (dir === 'on') {
1837
+ exp = `()=>{${exp}}`
1841
1838
  } else if (dir === 'for') {
1842
1839
  const inMatch = exp.match(forAliasRE)
1843
1840
  if (inMatch) {
@@ -38,7 +38,7 @@ function transform(
38
38
  }
39
39
 
40
40
  const imageCandidates: ImageCandidate[] = value
41
- .substr(1, value.length - 2)
41
+ .slice(1, -1)
42
42
  .split(',')
43
43
  .map(s => {
44
44
  // The attribute value arrives here with all whitespace, except
@@ -1562,5 +1562,17 @@ describe('SFC analyze <script> bindings', () => {
1562
1562
  expect(content).toMatch(`name: 'Baz'`)
1563
1563
  assertCode(content)
1564
1564
  })
1565
+
1566
+ // #12591
1567
+ test('should not error when performing ts expression check for v-on inline statement', () => {
1568
+ compile(`
1569
+ <script setup lang="ts">
1570
+ import { foo } from './foo'
1571
+ </script>
1572
+ <template>
1573
+ <div @click="$emit('update:a');"></div>
1574
+ </tempalte>
1575
+ `)
1576
+ })
1565
1577
  })
1566
1578
  })
@@ -181,7 +181,7 @@ export function defineReactive(
181
181
  }
182
182
  }
183
183
  }
184
- return isRef(value) ? value.value : value
184
+ return isRef(value) && !shallow ? value.value : value
185
185
  },
186
186
  set: function reactiveSetter(newVal) {
187
187
  const value = getter ? getter.call(obj) : val
@@ -361,6 +361,6 @@ export function hasChanged(x: unknown, y: unknown): boolean {
361
361
  if (x === y) {
362
362
  return x === 0 && 1 / x !== 1 / (y as number)
363
363
  } else {
364
- return x === x && y === y
364
+ return x === x || y === y
365
365
  }
366
366
  }
@@ -12,7 +12,7 @@ import {
12
12
  } from '../shared/util'
13
13
  import { currentInstance, setCurrentInstance } from './currentInstance'
14
14
  import { shallowReactive } from './reactivity/reactive'
15
- import { isRef } from './reactivity/ref'
15
+ import { proxyWithRefUnwrap } from './reactivity/ref'
16
16
 
17
17
  /**
18
18
  * @internal
@@ -68,7 +68,9 @@ export function initSetup(vm: Component) {
68
68
  // exposed for compiled render fn
69
69
  const proxy = (vm._setupProxy = {})
70
70
  for (const key in setupResult) {
71
- proxyWithRefUnwrap(proxy, setupResult, key)
71
+ if (key !== '__sfc') {
72
+ proxyWithRefUnwrap(proxy, setupResult, key)
73
+ }
72
74
  }
73
75
  }
74
76
  } else if (__DEV__ && setupResult !== undefined) {
@@ -81,25 +83,6 @@ export function initSetup(vm: Component) {
81
83
  }
82
84
  }
83
85
 
84
- export function proxyWithRefUnwrap(
85
- target: any,
86
- source: Record<string, any>,
87
- key: string
88
- ) {
89
- Object.defineProperty(target, key, {
90
- enumerable: true,
91
- configurable: true,
92
- get: () => {
93
- const raw = source[key]
94
- return isRef(raw) ? raw.value : raw
95
- },
96
- set: newVal => {
97
- const raw = source[key]
98
- isRef(raw) ? (raw.value = newVal) : (source[key] = newVal)
99
- }
100
- })
101
- }
102
-
103
86
  function createSetupContext(vm: Component): SetupContext {
104
87
  let exposeCalled = false
105
88
  return {
@@ -221,7 +221,7 @@ function doWatch(
221
221
  } else if (isFunction(source)) {
222
222
  if (cb) {
223
223
  // getter with cb
224
- getter = () => call(source as Function, WATCHER_GETTER)
224
+ getter = () => call(source, WATCHER_GETTER)
225
225
  } else {
226
226
  // no cb -> simple effect
227
227
  getter = () => {
@@ -231,7 +231,7 @@ function doWatch(
231
231
  if (cleanup) {
232
232
  cleanup()
233
233
  }
234
- return call(source as Function, WATCHER, [onCleanup])
234
+ return call(source, WATCHER, [onCleanup])
235
235
  }
236
236
  }
237
237
  } else {
package/src/v3/index.ts CHANGED
@@ -7,6 +7,7 @@ export {
7
7
  toRef,
8
8
  toRefs,
9
9
  unref,
10
+ proxyRefs,
10
11
  customRef,
11
12
  triggerRef,
12
13
  Ref,
@@ -93,6 +93,40 @@ export function unref<T>(ref: T | Ref<T>): T {
93
93
  return isRef(ref) ? (ref.value as any) : ref
94
94
  }
95
95
 
96
+ export function proxyRefs<T extends object>(
97
+ objectWithRefs: T
98
+ ): ShallowUnwrapRef<T> {
99
+ if (isReactive(objectWithRefs)) {
100
+ return objectWithRefs as any
101
+ }
102
+ const proxy = {}
103
+ const keys = Object.keys(objectWithRefs)
104
+ for (let i = 0; i < keys.length; i++) {
105
+ proxyWithRefUnwrap(proxy, objectWithRefs, keys[i])
106
+ }
107
+ return proxy as any
108
+ }
109
+
110
+ export function proxyWithRefUnwrap(
111
+ target: any,
112
+ source: Record<string, any>,
113
+ key: string
114
+ ) {
115
+ Object.defineProperty(target, key, {
116
+ enumerable: true,
117
+ configurable: true,
118
+ get: () => unref(source[key]),
119
+ set: value => {
120
+ const oldValue = source[key]
121
+ if (isRef(oldValue) && !isRef(value)) {
122
+ oldValue.value = value
123
+ } else {
124
+ source[key] = value
125
+ }
126
+ }
127
+ })
128
+ }
129
+
96
130
  export type CustomRefFactory<T> = (
97
131
  track: () => void,
98
132
  trigger: () => void
@@ -174,6 +174,8 @@ declare type PropOptions = {
174
174
 
175
175
  export declare function provide<T>(key: InjectionKey<T> | string | number, value: T): void;
176
176
 
177
+ export declare function proxyRefs<T extends object>(objectWithRefs: T): ShallowUnwrapRef<T>;
178
+
177
179
  declare const RawSymbol: unique symbol;
178
180
 
179
181
  export declare function reactive<T extends object>(target: T): UnwrapNestedRefs<T>;