From 810f6d12edea47cde7f39eaf7ec3ae1b7300d40c Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Sun, 21 Aug 2022 19:28:39 -0700 Subject: [PATCH 01/89] fix(types): Add missing type parameter constraints (#12754) --- types/options.d.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/types/options.d.ts b/types/options.d.ts index c82c6c5f8ae..9fcdaca624f 100644 --- a/types/options.d.ts +++ b/types/options.d.ts @@ -95,8 +95,8 @@ export type ThisTypedComponentOptionsWithArrayProps< Computed, PropNames extends string, SetupBindings, - Mixin, - Extends + Mixin extends ComponentOptionsMixin, + Extends extends ComponentOptionsMixin > = object & ComponentOptions< V, @@ -132,8 +132,8 @@ export type ThisTypedComponentOptionsWithRecordProps< Computed, Props, SetupBindings, - Mixin, - Extends + Mixin extends ComponentOptionsMixin, + Extends extends ComponentOptionsMixin > = object & ComponentOptions< V, From 46ca7bcddc06c50796ccff82d8c45693f1f14f47 Mon Sep 17 00:00:00 2001 From: Evan You Date: Tue, 23 Aug 2022 09:18:36 +0800 Subject: [PATCH 02/89] fix(compiler-sfc): avoid deindent when lang is jsx/tsx fix #12755 --- packages/compiler-sfc/src/parseComponent.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/compiler-sfc/src/parseComponent.ts b/packages/compiler-sfc/src/parseComponent.ts index 65b858c9fc0..05489280e63 100644 --- a/packages/compiler-sfc/src/parseComponent.ts +++ b/packages/compiler-sfc/src/parseComponent.ts @@ -179,11 +179,11 @@ export function parseComponent( let text = source.slice(currentBlock.start, currentBlock.end) if ( options.deindent === true || - // by default, deindent unless it's script with default lang or ts + // by default, deindent unless it's script with default lang or (j/t)sx? (options.deindent !== false && !( currentBlock.type === 'script' && - (!currentBlock.lang || currentBlock.lang === 'ts') + (!currentBlock.lang || /^(j|t)sx?$/.test(currentBlock.lang)) )) ) { text = deindent(text) From e0b26c483a1ba407a818b1fcba1a439df24e84a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=8D=E8=A7=81=E6=9C=88?= <61452855+nooooooom@users.noreply.github.com> Date: Tue, 23 Aug 2022 09:22:45 +0800 Subject: [PATCH 03/89] fix: fix parent of multi-nested HOC $el not updating (#12757) fix #12589 --- src/core/instance/lifecycle.ts | 11 +++++++++-- test/unit/modules/vdom/patch/edge-cases.spec.ts | 4 ++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/core/instance/lifecycle.ts b/src/core/instance/lifecycle.ts index df70b7113fd..94f42e27eb5 100644 --- a/src/core/instance/lifecycle.ts +++ b/src/core/instance/lifecycle.ts @@ -83,8 +83,15 @@ export function lifecycleMixin(Vue: typeof Component) { vm.$el.__vue__ = vm } // if parent is an HOC, update its $el as well - if (vm.$vnode && vm.$parent && vm.$vnode === vm.$parent._vnode) { - vm.$parent.$el = vm.$el + let wrapper: Component | undefined = vm + while ( + wrapper && + wrapper.$vnode && + wrapper.$parent && + wrapper.$vnode === wrapper.$parent._vnode + ) { + wrapper.$parent.$el = wrapper.$el + wrapper = wrapper.$parent } // updated hook is called by the scheduler to ensure that children are // updated in a parent's updated hook. diff --git a/test/unit/modules/vdom/patch/edge-cases.spec.ts b/test/unit/modules/vdom/patch/edge-cases.spec.ts index 10b8ad8179d..f9295533b1e 100644 --- a/test/unit/modules/vdom/patch/edge-cases.spec.ts +++ b/test/unit/modules/vdom/patch/edge-cases.spec.ts @@ -257,11 +257,15 @@ describe('vdom patch: edge cases', () => { expect(vm.$refs.foo.$refs.bar.$el.tagName).toBe('DIV') expect(vm.$refs.foo.$refs.bar.$el.className).toBe(`hello`) + expect(vm.$el.tagName).toBe('DIV') + expect(vm.$el.className).toBe(`hello`) vm.$refs.foo.$refs.bar.ok = false waitForUpdate(() => { expect(vm.$refs.foo.$refs.bar.$el.tagName).toBe('SPAN') expect(vm.$refs.foo.$refs.bar.$el.className).toBe(`hello`) + expect(vm.$el.tagName).toBe('SPAN') + expect(vm.$el.className).toBe(`hello`) }).then(done) }) From ee57d9fd1d51abe245c6c37e6f8f2d45977b929e Mon Sep 17 00:00:00 2001 From: Evan You Date: Tue, 23 Aug 2022 09:29:42 +0800 Subject: [PATCH 04/89] release: v2.7.10 --- CHANGELOG.md | 11 +++++++++++ package.json | 2 +- packages/compiler-sfc/package.json | 2 +- packages/server-renderer/package.json | 2 +- packages/template-compiler/package.json | 2 +- 5 files changed, 15 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b5d38472209..3ccae2540a9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,14 @@ +## [2.7.10](https://github.com/vuejs/vue/compare/v2.7.9...v2.7.10) (2022-08-23) + + +### Bug Fixes + +* **compiler-sfc:** avoid deindent when lang is jsx/tsx ([46ca7bc](https://github.com/vuejs/vue/commit/46ca7bcddc06c50796ccff82d8c45693f1f14f47)), closes [#12755](https://github.com/vuejs/vue/issues/12755) +* fix parent of multi-nested HOC $el not updating ([#12757](https://github.com/vuejs/vue/issues/12757)) ([e0b26c4](https://github.com/vuejs/vue/commit/e0b26c483a1ba407a818b1fcba1a439df24e84a8)), closes [#12589](https://github.com/vuejs/vue/issues/12589) +* **types:** Add missing type parameter constraints ([#12754](https://github.com/vuejs/vue/issues/12754)) ([810f6d1](https://github.com/vuejs/vue/commit/810f6d12edea47cde7f39eaf7ec3ae1b7300d40c)) + + + ## [2.7.9](https://github.com/vuejs/vue/compare/v2.7.8...v2.7.9) (2022-08-19) diff --git a/package.json b/package.json index 0bbc17d6b0b..e8750ff7385 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "vue", - "version": "2.7.9", + "version": "2.7.10", "packageManager": "pnpm@7.1.0", "description": "Reactive, component-oriented view layer for modern web interfaces.", "main": "dist/vue.runtime.common.js", diff --git a/packages/compiler-sfc/package.json b/packages/compiler-sfc/package.json index 3e88b96778c..115ae6e775b 100644 --- a/packages/compiler-sfc/package.json +++ b/packages/compiler-sfc/package.json @@ -1,6 +1,6 @@ { "name": "@vue/compiler-sfc", - "version": "2.7.9", + "version": "2.7.10", "description": "compiler-sfc for Vue 2", "main": "dist/compiler-sfc.js", "types": "dist/compiler-sfc.d.ts", diff --git a/packages/server-renderer/package.json b/packages/server-renderer/package.json index 784b7838cbe..5470ebfaca3 100644 --- a/packages/server-renderer/package.json +++ b/packages/server-renderer/package.json @@ -1,6 +1,6 @@ { "name": "vue-server-renderer", - "version": "2.7.9", + "version": "2.7.10", "description": "server renderer for Vue 2.0", "main": "index.js", "types": "types/index.d.ts", diff --git a/packages/template-compiler/package.json b/packages/template-compiler/package.json index 26bf6586f94..75285bc0e85 100644 --- a/packages/template-compiler/package.json +++ b/packages/template-compiler/package.json @@ -1,6 +1,6 @@ { "name": "vue-template-compiler", - "version": "2.7.9", + "version": "2.7.10", "description": "template compiler for Vue 2.0", "main": "index.js", "unpkg": "browser.js", From d189b4beaa90b9fe58fd3f66ba9e09d340755196 Mon Sep 17 00:00:00 2001 From: Evan You Date: Thu, 1 Sep 2022 14:30:09 +0800 Subject: [PATCH 05/89] chore: special sponsor [ci skip] --- README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/README.md b/README.md index 5eef53d3fa0..cfaef3e361e 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,16 @@ You are looking at the repository for Vue 2. The repo for Vue 3 is [vuejs/core]( Vue.js is an MIT-licensed open source project with its ongoing development made possible entirely by the support of these awesome [backers](https://github.com/vuejs/core/blob/main/BACKERS.md). If you'd like to join them, please consider [ sponsor Vue's development](https://vuejs.org/sponsor/). +

+

Special Sponsor

+

+ +

+ + special sponsor appwrite + +

+

sponsors From 60d268c4261a0b9c5125f308468b31996a8145ad Mon Sep 17 00:00:00 2001 From: Evan You Date: Thu, 1 Sep 2022 14:31:31 +0800 Subject: [PATCH 06/89] chore: cache bust svg [ci skip] --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index cfaef3e361e..bca41a49405 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ Vue.js is an MIT-licensed open source project with its ongoing development made

- sponsors + sponsors

From 2f335b2f9d09b962f40e38740826d444e4fff073 Mon Sep 17 00:00:00 2001 From: Evan You Date: Tue, 11 Oct 2022 11:41:31 +0800 Subject: [PATCH 07/89] fix(sfc): remove sfc scoped deep syntax deprecation warnings --- .../compiler-sfc/src/stylePlugins/scoped.ts | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/packages/compiler-sfc/src/stylePlugins/scoped.ts b/packages/compiler-sfc/src/stylePlugins/scoped.ts index 25332731ef6..55f17c386f3 100644 --- a/packages/compiler-sfc/src/stylePlugins/scoped.ts +++ b/packages/compiler-sfc/src/stylePlugins/scoped.ts @@ -1,6 +1,5 @@ import { PluginCreator, Rule, AtRule } from 'postcss' import selectorParser from 'postcss-selector-parser' -import { warn } from '../warn' const animationNameRE = /^(-\w+-)?animation-name$/ const animationRE = /^(-\w+-)?animation$/ @@ -94,10 +93,10 @@ function rewriteSelector( ) { n.value = ' ' n.spaces.before = n.spaces.after = '' - warn( - `the >>> and /deep/ combinators have been deprecated. ` + - `Use :deep() instead.` - ) + // warn( + // `the >>> and /deep/ combinators have been deprecated. ` + + // `Use :deep() instead.` + // ) return false } @@ -126,12 +125,12 @@ function rewriteSelector( } selector.removeChild(n) } else { - // DEPRECATED usage + // DEPRECATED usage in v3 // .foo ::v-deep .bar -> .foo[xxxxxxx] .bar - warn( - `::v-deep usage as a combinator has ` + - `been deprecated. Use :deep() instead.` - ) + // warn( + // `::v-deep usage as a combinator has ` + + // `been deprecated. Use :deep() instead.` + // ) const prev = selector.at(selector.index(n) - 1) if (prev && isSpaceCombinator(prev)) { selector.removeChild(prev) From 27eed829ccf9978a63b8cd989ff4c03897276bc2 Mon Sep 17 00:00:00 2001 From: ZHAO Jinxiang Date: Mon, 10 Oct 2022 20:51:05 -0700 Subject: [PATCH 08/89] fix(types): vue 3 directive type compatibility (#12792) --- types/options.d.ts | 7 +++++++ types/vue.d.ts | 5 +++++ 2 files changed, 12 insertions(+) diff --git a/types/options.d.ts b/types/options.d.ts index 9fcdaca624f..93379edbef2 100644 --- a/types/options.d.ts +++ b/types/options.d.ts @@ -4,6 +4,7 @@ import { SetupContext } from './v3-setup-context' import { DebuggerEvent } from './v3-generated' import { DefineComponent } from './v3-define-component' import { ComponentOptionsMixin } from './v3-component-options' +import { ObjectDirective, FunctionDirective } from './v3-directive' type Constructor = { new (...args: any[]): any @@ -318,6 +319,9 @@ export interface DirectiveBinding extends Readonly { readonly modifiers: { [key: string]: boolean } } +/** + * @deprecated use {@link FunctionDirective} instead + */ export type DirectiveFunction = ( el: HTMLElement, binding: DirectiveBinding, @@ -325,6 +329,9 @@ export type DirectiveFunction = ( oldVnode: VNode ) => void +/** + * @deprecated use {@link ObjectDirective} instead + */ export interface DirectiveOptions { bind?: DirectiveFunction inserted?: DirectiveFunction diff --git a/types/vue.d.ts b/types/vue.d.ts index 5a2027a0179..f158cf01716 100644 --- a/types/vue.d.ts +++ b/types/vue.d.ts @@ -22,6 +22,7 @@ import { ExtractComputedReturns, ComponentOptionsMixin } from './v3-component-options' +import { Directive, ObjectDirective } from './v3-directive' export interface CreateElement { ( @@ -338,6 +339,10 @@ export interface VueConstructor { id: string, definition?: DirectiveOptions | DirectiveFunction ): DirectiveOptions + directive( + id: string, + definition?: Directive + ): ObjectDirective filter(id: string, definition?: Function): Function component(id: string): VueConstructor From 4a0d88e46e4180edc7f22e36c25df3f8ac5d60d2 Mon Sep 17 00:00:00 2001 From: Evan You Date: Tue, 11 Oct 2022 12:26:19 +0800 Subject: [PATCH 09/89] fix(reactivity): use WeakMap for proxy/raw checks, compat with non-extensible objects fix #12799 close #12798 --- src/core/observer/index.ts | 4 +++- src/v3/reactivity/reactive.ts | 9 +++++++-- src/v3/reactivity/readonly.ts | 10 +++++----- test/unit/features/v3/reactivity/reactive.spec.ts | 6 ++++++ test/unit/features/v3/reactivity/readonly.spec.ts | 7 +++++++ 5 files changed, 28 insertions(+), 8 deletions(-) diff --git a/src/core/observer/index.ts b/src/core/observer/index.ts index 3770c489a9f..dcf6bde1e76 100644 --- a/src/core/observer/index.ts +++ b/src/core/observer/index.ts @@ -17,6 +17,7 @@ import { noop } from '../util/index' import { isReadonly, isRef, TrackOpTypes, TriggerOpTypes } from '../../v3' +import { rawMap } from '../../v3/reactivity/reactive' const arrayKeys = Object.getOwnPropertyNames(arrayMethods) @@ -118,7 +119,8 @@ export function observe( (ssrMockReactivity || !isServerRendering()) && (isArray(value) || isPlainObject(value)) && Object.isExtensible(value) && - !value.__v_skip /* ReactiveFlags.SKIP */ + !value.__v_skip /* ReactiveFlags.SKIP */ && + !rawMap.has(value) ) { ob = new Observer(value, shallow, ssrMockReactivity) } diff --git a/src/v3/reactivity/reactive.ts b/src/v3/reactivity/reactive.ts index 0ff682243a2..c65f25e67d8 100644 --- a/src/v3/reactivity/reactive.ts +++ b/src/v3/reactivity/reactive.ts @@ -5,10 +5,13 @@ import { isPrimitive, warn, toRawType, - isServerRendering + isServerRendering, + isObject } from 'core/util' import type { Ref, UnwrapRefSimple, RawSymbol } from './ref' +export const rawMap = new WeakMap() + export const enum ReactiveFlags { SKIP = '__v_skip', IS_READONLY = '__v_isReadonly', @@ -119,7 +122,9 @@ export function toRaw(observed: T): T { export function markRaw( value: T ): T & { [RawSymbol]?: true } { - def(value, ReactiveFlags.SKIP, true) + if (isObject(value)) { + rawMap.set(value, true) + } return value } diff --git a/src/v3/reactivity/readonly.ts b/src/v3/reactivity/readonly.ts index 933f910b69f..c3794bb53b3 100644 --- a/src/v3/reactivity/readonly.ts +++ b/src/v3/reactivity/readonly.ts @@ -32,8 +32,8 @@ export type DeepReadonly = T extends Builtin ? { readonly [K in keyof T]: DeepReadonly } : Readonly -const rawToReadonlyFlag = `__v_rawToReadonly` -const rawToShallowReadonlyFlag = `__v_rawToShallowReadonly` +const rawToReadonlyMap = new WeakMap() +const rawToShallowReadonlyMap = new WeakMap() export function readonly( target: T @@ -63,14 +63,14 @@ function createReadonly(target: any, shallow: boolean) { } // already has a readonly proxy - const existingFlag = shallow ? rawToShallowReadonlyFlag : rawToReadonlyFlag - const existingProxy = target[existingFlag] + const map = shallow ? rawToShallowReadonlyMap : rawToReadonlyMap + const existingProxy = map.get(target) if (existingProxy) { return existingProxy } const proxy = Object.create(Object.getPrototypeOf(target)) - def(target, existingFlag, proxy) + map.set(target, proxy) def(proxy, ReactiveFlags.IS_READONLY, true) def(proxy, ReactiveFlags.RAW, target) diff --git a/test/unit/features/v3/reactivity/reactive.spec.ts b/test/unit/features/v3/reactivity/reactive.spec.ts index f636d44d4a1..a8a30e0353c 100644 --- a/test/unit/features/v3/reactivity/reactive.spec.ts +++ b/test/unit/features/v3/reactivity/reactive.spec.ts @@ -258,6 +258,12 @@ describe('reactivity/reactive', () => { expect(isReactive(obj.bar)).toBe(false) }) + test('markRaw on non-extensible objects', () => { + const foo = Object.freeze({}) + markRaw(foo) + expect(isReactive(reactive(foo))).toBe(false) + }) + test('should not observe non-extensible objects', () => { const obj = reactive({ foo: Object.preventExtensions({ a: 1 }), diff --git a/test/unit/features/v3/reactivity/readonly.spec.ts b/test/unit/features/v3/reactivity/readonly.spec.ts index 012e142d451..fab99bbfbcb 100644 --- a/test/unit/features/v3/reactivity/readonly.spec.ts +++ b/test/unit/features/v3/reactivity/readonly.spec.ts @@ -525,4 +525,11 @@ describe('reactivity/readonly', () => { expect(readonlyFoo.x).toBe(1) expect(`et operation on key "x" failed`).toHaveBeenWarned() }) + + test('compatibility with non-extensible objects', () => { + const foo = Object.freeze({ a: 1 }) + const bar = readonly(foo) + expect(isReadonly(bar)).toBe(true) + expect(readonly(foo)).toBe(bar) + }) }) From 5d26f815c643d41e6ca6f29329593223b981fc24 Mon Sep 17 00:00:00 2001 From: Xiersa Date: Tue, 11 Oct 2022 13:26:20 +0800 Subject: [PATCH 10/89] fix(reactivity): check skip first before checking ref when creating observer (#12813) fix #12812 --- src/core/observer/index.ts | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/src/core/observer/index.ts b/src/core/observer/index.ts index dcf6bde1e76..51f928c5c24 100644 --- a/src/core/observer/index.ts +++ b/src/core/observer/index.ts @@ -7,7 +7,6 @@ import { hasOwn, isArray, hasProto, - isObject, isPlainObject, isPrimitive, isUndef, @@ -108,23 +107,21 @@ export function observe( shallow?: boolean, ssrMockReactivity?: boolean ): Observer | void { - if (!isObject(value) || isRef(value) || value instanceof VNode) { - return + if (value && hasOwn(value, '__ob__') && value.__ob__ instanceof Observer) { + return value.__ob__ } - let ob: Observer | void - if (hasOwn(value, '__ob__') && value.__ob__ instanceof Observer) { - ob = value.__ob__ - } else if ( + if ( shouldObserve && (ssrMockReactivity || !isServerRendering()) && (isArray(value) || isPlainObject(value)) && Object.isExtensible(value) && !value.__v_skip /* ReactiveFlags.SKIP */ && - !rawMap.has(value) + !rawMap.has(value) && + !isRef(value) && + !(value instanceof VNode) ) { - ob = new Observer(value, shallow, ssrMockReactivity) + return new Observer(value, shallow, ssrMockReactivity) } - return ob } /** From 87f69aa26f195390b948fbb0ff62cf954b58c82c Mon Sep 17 00:00:00 2001 From: Shiluo34 Date: Tue, 11 Oct 2022 13:36:50 +0800 Subject: [PATCH 11/89] fix(types): support Ref and function types in tsx ref attribute (#12759) fix #12758 --- types/test/v3/tsx-test.tsx | 7 ++++++- types/vnode.d.ts | 12 +++++++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/types/test/v3/tsx-test.tsx b/types/test/v3/tsx-test.tsx index 16a767acc5a..286c16997a0 100644 --- a/types/test/v3/tsx-test.tsx +++ b/types/test/v3/tsx-test.tsx @@ -1,4 +1,4 @@ -import { VNode, defineComponent } from '../../index' +import { VNode, defineComponent, ref } from '../../index' import { expectType } from '../utils' expectType(
) @@ -22,6 +22,11 @@ expectError(
) expectType(
) expectType(
) +// allow Ref type type on arbitrary element +const fooRef = ref() +expectType(
) +expectType(
{fooRef.value = el as HTMLElement}} />) + expectType( { diff --git a/types/vnode.d.ts b/types/vnode.d.ts index 7a543f0a39b..29bdb398c1c 100644 --- a/types/vnode.d.ts +++ b/types/vnode.d.ts @@ -1,5 +1,7 @@ import { Vue } from './vue' import { DirectiveFunction, DirectiveOptions } from './options' +import { Ref } from './v3-generated' +import { ComponentPublicInstance } from './v3-component-public-instance' /** * For extending allowed non-declared props on components in TSX @@ -65,11 +67,19 @@ export interface VNodeComponentOptions { tag?: string } +export type VNodeRef = + | string + | Ref + | (( + ref: Element | ComponentPublicInstance | null, + refs: Record + ) => void) + export interface VNodeData { key?: string | number slot?: string scopedSlots?: { [key: string]: ScopedSlot | undefined } - ref?: string + ref?: VNodeRef refInFor?: boolean tag?: string staticClass?: string From fb1393009660b38046b1f6dfb532b481cc53b3b7 Mon Sep 17 00:00:00 2001 From: Evan You Date: Tue, 11 Oct 2022 14:09:10 +0800 Subject: [PATCH 12/89] fix(sfc): prune returned bindings for non-TS as well In Vue 3, pruning is only done for TS to produce valid code and tree-shaking is done by inlining the template for production. In Vue 2 we do not inline the template in production, so return binding pruning is needed in all cases. fix #12765 --- packages/compiler-sfc/src/compileScript.ts | 36 +++++++++---------- .../__snapshots__/compileScript.spec.ts.snap | 2 +- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/packages/compiler-sfc/src/compileScript.ts b/packages/compiler-sfc/src/compileScript.ts index 094120c38f7..7d171a9b78a 100644 --- a/packages/compiler-sfc/src/compileScript.ts +++ b/packages/compiler-sfc/src/compileScript.ts @@ -284,11 +284,9 @@ export function compileScript( userImportAlias[imported] = local } - // template usage check is only needed in non-inline mode, so we can skip - // the work if inlineTemplate is true. let isUsedInTemplate = true - if (isTS && sfc.template && !sfc.template.src && !sfc.template.lang) { - isUsedInTemplate = isImportUsed(local, sfc) + if (sfc.template && !sfc.template.src && !sfc.template.lang) { + isUsedInTemplate = isImportUsed(local, sfc, isTS) } userImports[local] = { @@ -1782,7 +1780,7 @@ function getObjectOrArrayExpressionKeys(value: Node): string[] { const templateUsageCheckCache = new LRU(512) -function resolveTemplateUsageCheckString(sfc: SFCDescriptor) { +function resolveTemplateUsageCheckString(sfc: SFCDescriptor, isTS: boolean) { const { content } = sfc.template! const cached = templateUsageCheckCache.get(content) if (cached) { @@ -1809,7 +1807,7 @@ function resolveTemplateUsageCheckString(sfc: SFCDescriptor) { code += `,v${capitalize(camelize(baseName))}` } if (value) { - code += `,${processExp(value, baseName)}` + code += `,${processExp(value, isTS, baseName)}` } } } @@ -1817,7 +1815,7 @@ function resolveTemplateUsageCheckString(sfc: SFCDescriptor) { chars(text) { const res = parseText(text) if (res) { - code += `,${processExp(res.expression)}` + code += `,${processExp(res.expression, isTS)}` } } }) @@ -1829,8 +1827,8 @@ function resolveTemplateUsageCheckString(sfc: SFCDescriptor) { const forAliasRE = /([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/ -function processExp(exp: string, dir?: string): string { - if (/ as\s+\w|<.*>|:/.test(exp)) { +function processExp(exp: string, isTS: boolean, dir?: string): string { + if (isTS && / as\s+\w|<.*>|:/.test(exp)) { if (dir === 'slot') { exp = `(${exp})=>{}` } else if (dir === 'on') { @@ -1839,7 +1837,7 @@ function processExp(exp: string, dir?: string): string { const inMatch = exp.match(forAliasRE) if (inMatch) { const [, LHS, RHS] = inMatch - return processExp(`(${LHS})=>{}`) + processExp(RHS) + return processExp(`(${LHS})=>{}`, true) + processExp(RHS, true) } } let ret = '' @@ -1867,36 +1865,38 @@ function stripTemplateString(str: string): string { return '' } -function isImportUsed(local: string, sfc: SFCDescriptor): boolean { +function isImportUsed( + local: string, + sfc: SFCDescriptor, + isTS: boolean +): boolean { return new RegExp( // #4274 escape $ since it's a special char in regex // (and is the only regex special char that is valid in identifiers) `[^\\w$_]${local.replace(/\$/g, '\\$')}[^\\w$_]` - ).test(resolveTemplateUsageCheckString(sfc)) + ).test(resolveTemplateUsageCheckString(sfc, isTS)) } /** * Note: this comparison assumes the prev/next script are already identical, - * and only checks the special case where `) }) }) From 0b3cf7dda9ac605b2b9f799acacd2793e974f225 Mon Sep 17 00:00:00 2001 From: webfansplz <308241863@qq.com> Date: Wed, 9 Nov 2022 17:25:28 +0800 Subject: [PATCH 30/89] fix(types): stricter type condition for `EventHandlers` (#12840) fix #12832 --- types/jsx.d.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/types/jsx.d.ts b/types/jsx.d.ts index 4924f4c643c..845cfdcb030 100644 --- a/types/jsx.d.ts +++ b/types/jsx.d.ts @@ -1297,7 +1297,9 @@ export interface Events { } type EventHandlers = { - [K in keyof E]?: E[K] extends Function ? E[K] : (payload: E[K]) => void + [K in keyof E]?: E[K] extends (...args: any) => any + ? E[K] + : (payload: E[K]) => void } type ReservedProps = { From f7db7f361b6356591781b9f33abbb0d5b7f9b97c Mon Sep 17 00:00:00 2001 From: k-furusho <88301866+k-furusho@users.noreply.github.com> Date: Wed, 9 Nov 2022 18:34:55 +0900 Subject: [PATCH 31/89] fix(types): fix spreading VNodeData in tsx (#12789) fix #12778 --- types/test/vue-test.ts | 14 +++++++------- types/vnode.d.ts | 3 ++- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/types/test/vue-test.ts b/types/test/vue-test.ts index b792cec583d..fdf37b52abb 100644 --- a/types/test/vue-test.ts +++ b/types/test/vue-test.ts @@ -228,21 +228,21 @@ obj.a++ const ComponentWithStyleInVNodeData = Vue.extend({ render(h) { const elementWithStyleAsString = h('div', { - style: 'background-color: red;' + style: '--theme-color: black;' }) - const elementWithStyleAsObject = h('div', { - style: { backgroundColor: 'green' } + const elementWithStyleCSSProperties = h('div', { + style: { ['--theme-color' as any]: 'black' } }) - const elementWithStyleAsArrayOfObjects = h('div', { - style: [{ backgroundColor: 'blue' }] + const elementWithStyleAsArrayOfStyleValues = h('div', { + style: [{ ['--theme-color' as any]: 'black' }] }) return h('div', undefined, [ elementWithStyleAsString, - elementWithStyleAsObject, - elementWithStyleAsArrayOfObjects + elementWithStyleCSSProperties, + elementWithStyleAsArrayOfStyleValues ]) } }) diff --git a/types/vnode.d.ts b/types/vnode.d.ts index 29bdb398c1c..d6f23ec3b67 100644 --- a/types/vnode.d.ts +++ b/types/vnode.d.ts @@ -1,3 +1,4 @@ +import { StyleValue } from './jsx' import { Vue } from './vue' import { DirectiveFunction, DirectiveOptions } from './options' import { Ref } from './v3-generated' @@ -85,7 +86,7 @@ export interface VNodeData { staticClass?: string class?: any staticStyle?: { [key: string]: any } - style?: string | object[] | object + style?: StyleValue props?: { [key: string]: any } attrs?: { [key: string]: any } domProps?: { [key: string]: any } From 5aed733ab6b6605314cc5f24cc1b1dd9aa4413c8 Mon Sep 17 00:00:00 2001 From: Evan You Date: Wed, 9 Nov 2022 17:35:45 +0800 Subject: [PATCH 32/89] test: add test case for #12778 --- types/test/v3/tsx-test.tsx | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/types/test/v3/tsx-test.tsx b/types/test/v3/tsx-test.tsx index 286c16997a0..6a9dcce4fc1 100644 --- a/types/test/v3/tsx-test.tsx +++ b/types/test/v3/tsx-test.tsx @@ -1,4 +1,4 @@ -import { VNode, defineComponent, ref } from '../../index' +import { VNode, defineComponent, ref, RenderContext } from '../../index' import { expectType } from '../utils' expectType(
) @@ -25,7 +25,13 @@ expectType(
) // allow Ref type type on arbitrary element const fooRef = ref() expectType(
) -expectType(
{fooRef.value = el as HTMLElement}} />) +expectType( +
{ + fooRef.value = el as HTMLElement + }} + /> +) expectType( ; - ;
+ +export default ({ data }: RenderContext) => { + return