Browse Source

fix(sfc): fix sfc name inference type check

fix #12637
Evan You 3 years ago
parent
commit
04b4703de7

+ 5 - 4
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<string, CacheEntry | null>
 
-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

+ 3 - 1
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)
     }

+ 2 - 1
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$/)

+ 5 - 1
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}` : ''}`,

+ 2 - 1
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(`<transition-group> children must be keyed: <${name}>`)
         }

+ 2 - 0
types/options.d.ts

@@ -219,6 +219,8 @@ export interface ComponentOptions<
   parent?: Vue
   mixins?: (ComponentOptions<Vue> | typeof Vue)[]
   name?: string
+  // for SFC auto name inference w/ ts-loader check
+  __name?: string
   // TODO: support properly inferred 'extends'
   extends?: ComponentOptions<Vue> | typeof Vue
   delimiters?: [string, string]