From 04b4703de72b1c1e686a3aa81d5b5b56799dabab Mon Sep 17 00:00:00 2001 From: Evan You Date: Tue, 12 Jul 2022 17:39:45 +0800 Subject: [PATCH] fix(sfc): fix sfc name inference type check fix #12637 --- src/core/components/keep-alive.ts | 9 +++++---- src/core/global-api/extend.ts | 4 +++- src/core/util/debug.ts | 3 ++- src/core/vdom/create-component.ts | 6 +++++- src/platforms/web/runtime/components/transition-group.ts | 3 ++- types/options.d.ts | 2 ++ 6 files changed, 19 insertions(+), 8 deletions(-) diff --git a/src/core/components/keep-alive.ts b/src/core/components/keep-alive.ts index c2676a35574..2bb2206be37 100644 --- a/src/core/components/keep-alive.ts +++ b/src/core/components/keep-alive.ts @@ -3,6 +3,7 @@ import { getFirstComponentChild } from 'core/vdom/helpers/index' import type VNode from 'core/vdom/vnode' import type { VNodeComponentOptions } from 'types/vnode' import type { Component } from 'types/component' +import { getComponentName } from '../vdom/create-component' type CacheEntry = { name?: string @@ -12,8 +13,8 @@ type CacheEntry = { type CacheEntryMap = Record -function getComponentName(opts?: VNodeComponentOptions): string | null { - return opts && (opts.Ctor.options.name || opts.tag) +function _getComponentName(opts?: VNodeComponentOptions): string | null { + return opts && (getComponentName(opts.Ctor.options as any) || opts.tag) } function matches( @@ -81,7 +82,7 @@ export default { if (vnodeToCache) { const { tag, componentInstance, componentOptions } = vnodeToCache cache[keyToCache] = { - name: getComponentName(componentOptions), + name: _getComponentName(componentOptions), tag, componentInstance } @@ -126,7 +127,7 @@ export default { const componentOptions = vnode && vnode.componentOptions if (componentOptions) { // check pattern - const name = getComponentName(componentOptions) + const name = _getComponentName(componentOptions) const { include, exclude } = this if ( // not included diff --git a/src/core/global-api/extend.ts b/src/core/global-api/extend.ts index 5fed6fe90a9..800e8c2329e 100644 --- a/src/core/global-api/extend.ts +++ b/src/core/global-api/extend.ts @@ -3,6 +3,7 @@ import type { Component } from 'types/component' import type { GlobalAPI } from 'types/global-api' import { defineComputed, proxy } from '../instance/state' import { extend, mergeOptions, validateComponentName } from '../util/index' +import { getComponentName } from '../vdom/create-component' export function initExtend(Vue: GlobalAPI) { /** @@ -25,7 +26,8 @@ export function initExtend(Vue: GlobalAPI) { return cachedCtors[SuperId] } - const name = extendOptions.name || Super.options.name + const name = + getComponentName(extendOptions) || getComponentName(Super.options) if (__DEV__ && name) { validateComponentName(name) } diff --git a/src/core/util/debug.ts b/src/core/util/debug.ts index 8dbc1edb19a..891f0177c68 100644 --- a/src/core/util/debug.ts +++ b/src/core/util/debug.ts @@ -2,6 +2,7 @@ import config from '../config' import { noop, isArray, isFunction } from 'shared/util' import type { Component } from 'types/component' import { currentInstance } from 'v3/currentInstance' +import { getComponentName } from '../vdom/create-component' export let warn: (msg: string, vm?: Component | null) => void = noop export let tip = noop @@ -40,7 +41,7 @@ if (__DEV__) { : vm._isVue ? vm.$options || (vm.constructor as any).options : vm - let name = options.name || options._componentTag + let name = getComponentName(options) const file = options.__file if (!name && file) { const match = file.match(/([^/\\]+)\.vue$/) diff --git a/src/core/vdom/create-component.ts b/src/core/vdom/create-component.ts index 7ec6d82038b..9e48c575230 100644 --- a/src/core/vdom/create-component.ts +++ b/src/core/vdom/create-component.ts @@ -28,6 +28,10 @@ import type { import type { Component } from 'types/component' import type { ComponentOptions, InternalComponentOptions } from 'types/options' +export function getComponentName(options: ComponentOptions) { + return options.name || options.__name || options._componentTag +} + // inline hooks to be invoked on component VNodes during patch const componentVNodeHooks = { init(vnode: VNodeWithData, hydrating: boolean): boolean | void { @@ -188,7 +192,7 @@ export function createComponent( // return a placeholder vnode // @ts-expect-error - const name = Ctor.options.name || tag + const name = getComponentName(Ctor.options) || tag const vnode = new VNode( // @ts-expect-error `vue-component-${Ctor.cid}${name ? `-${name}` : ''}`, diff --git a/src/platforms/web/runtime/components/transition-group.ts b/src/platforms/web/runtime/components/transition-group.ts index d7a454d3e19..8588ea80561 100644 --- a/src/platforms/web/runtime/components/transition-group.ts +++ b/src/platforms/web/runtime/components/transition-group.ts @@ -23,6 +23,7 @@ import { } from 'web/runtime/transition-util' import VNode from 'core/vdom/vnode' import { VNodeWithData } from 'types/vnode' +import { getComponentName } from 'core/vdom/create-component' const props = extend( { @@ -72,7 +73,7 @@ export default { } else if (__DEV__) { const opts = c.componentOptions const name: string = opts - ? opts.Ctor.options.name || opts.tag || '' + ? getComponentName(opts.Ctor.options as any) || opts.tag || '' : c.tag warn(` children must be keyed: <${name}>`) } diff --git a/types/options.d.ts b/types/options.d.ts index 736da7ade30..e11020f4948 100644 --- a/types/options.d.ts +++ b/types/options.d.ts @@ -219,6 +219,8 @@ export interface ComponentOptions< parent?: Vue mixins?: (ComponentOptions | typeof Vue)[] name?: string + // for SFC auto name inference w/ ts-loader check + __name?: string // TODO: support properly inferred 'extends' extends?: ComponentOptions | typeof Vue delimiters?: [string, string]