]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(build): fix component resolution when disabling options API
authorEvan You <yyx990803@gmail.com>
Thu, 23 Jul 2020 18:33:15 +0000 (14:33 -0400)
committerEvan You <yyx990803@gmail.com>
Thu, 23 Jul 2020 18:33:15 +0000 (14:33 -0400)
fix #1688

packages/runtime-core/src/component.ts
packages/runtime-core/src/componentOptions.ts
packages/runtime-core/src/helpers/resolveAssets.ts

index 9efb657e9c599825e7078c0432611e9a45b2881e..da6d51c1bb27a153c557a6fb9a19995bd67e4cbc 100644 (file)
@@ -24,7 +24,7 @@ import { Slots, initSlots, InternalSlots } from './componentSlots'
 import { warn } from './warning'
 import { ErrorCodes, callWithErrorHandling } from './errorHandling'
 import { AppContext, createAppContext, AppConfig } from './apiCreateApp'
-import { Directive, validateDirectiveName } from './directives'
+import { validateDirectiveName } from './directives'
 import { applyOptions, ComponentOptions } from './componentOptions'
 import {
   EmitsOptions,
@@ -223,17 +223,6 @@ export interface ComponentInternalInstance {
    */
   renderCache: (Function | VNode)[]
 
-  /**
-   * Asset hashes that prototypally inherits app-level asset hashes for fast
-   * resolution
-   * @internal
-   */
-  components: Record<string, Component>
-  /**
-   * @internal
-   */
-  directives: Record<string, Directive>
-
   // the rest are only for stateful components ---------------------------------
 
   // main proxy that serves as the public instance (`this`)
@@ -354,15 +343,17 @@ export function createComponentInstance(
   parent: ComponentInternalInstance | null,
   suspense: SuspenseBoundary | null
 ) {
+  const type = vnode.type as Component
   // inherit parent app context - or - if root, adopt from root vnode
   const appContext =
     (parent ? parent.appContext : vnode.appContext) || emptyAppContext
+
   const instance: ComponentInternalInstance = {
     uid: uid++,
     vnode,
+    type,
     parent,
     appContext,
-    type: vnode.type as Component,
     root: null!, // to be immediately set
     next: null,
     subTree: null!, // will be set synchronously right after creation
@@ -385,10 +376,6 @@ export function createComponentInstance(
     setupState: EMPTY_OBJ,
     setupContext: null,
 
-    // per-instance asset storage (mutable during options resolution)
-    components: Object.create(appContext.components),
-    directives: Object.create(appContext.directives),
-
     // suspense related
     suspense,
     asyncDep: null,
@@ -727,14 +714,18 @@ export function formatComponentName(
   }
 
   if (!name && instance && instance.parent) {
-    // try to infer the name based on local resolution
-    const registry = instance.parent.components
-    for (const key in registry) {
-      if (registry[key] === Component) {
-        name = key
-        break
+    // try to infer the name based on reverse resolution
+    const inferFromRegistry = (registry: Record<string, any> | undefined) => {
+      for (const key in registry) {
+        if (registry[key] === Component) {
+          return key
+        }
       }
     }
+    name =
+      inferFromRegistry(
+        (instance.parent.type as ComponentOptions).components
+      ) || inferFromRegistry(instance.appContext.components)
   }
 
   return name ? classify(name) : isRoot ? `App` : `Anonymous`
index 948ceafc53835143f5e70cdf6f08f03f7cd1c78c..247ea946d47ac574b3444433c9a93a608a603f43 100644 (file)
@@ -381,9 +381,6 @@ export function applyOptions(
     watch: watchOptions,
     provide: provideOptions,
     inject: injectOptions,
-    // assets
-    components,
-    directives,
     // lifecycle
     beforeMount,
     mounted,
@@ -570,14 +567,6 @@ export function applyOptions(
     }
   }
 
-  // asset options
-  if (components) {
-    extend(instance.components, components)
-  }
-  if (directives) {
-    extend(instance.directives, directives)
-  }
-
   // lifecycle options
   if (!asMixin) {
     callSyncHook('created', options, publicThis, globalMixins)
index 03a83337b979648fa44f77156545b432faa2bc08..3272317dfb978975c8a447b3248c983f87f91828 100644 (file)
@@ -1,5 +1,10 @@
 import { currentRenderingInstance } from '../componentRenderUtils'
-import { currentInstance, Component, FunctionalComponent } from '../component'
+import {
+  currentInstance,
+  Component,
+  FunctionalComponent,
+  ComponentOptions
+} from '../component'
 import { Directive } from '../directives'
 import { camelize, capitalize, isString } from '@vue/shared'
 import { warn } from '../warning'
@@ -58,24 +63,27 @@ function resolveAsset(
 ) {
   const instance = currentRenderingInstance || currentInstance
   if (instance) {
-    let camelized, capitalized
-    const registry = instance[type]
-    let res =
-      registry[name] ||
-      registry[(camelized = camelize(name))] ||
-      registry[(capitalized = capitalize(camelized))]
-    if (!res && type === COMPONENTS) {
-      const self = instance.type
-      const selfName = (self as FunctionalComponent).displayName || self.name
+    const Component = instance.type
+
+    // self name has highest priority
+    if (type === COMPONENTS) {
+      const selfName =
+        (Component as FunctionalComponent).displayName || Component.name
       if (
         selfName &&
         (selfName === name ||
-          selfName === camelized ||
-          selfName === capitalized)
+          selfName === camelize(name) ||
+          selfName === capitalize(camelize(name)))
       ) {
-        res = self
+        return Component
       }
     }
+
+    const res =
+      // local registration
+      resolve((Component as ComponentOptions)[type], name) ||
+      // global registration
+      resolve(instance.appContext[type], name)
     if (__DEV__ && warnMissing && !res) {
       warn(`Failed to resolve ${type.slice(0, -1)}: ${name}`)
     }
@@ -87,3 +95,12 @@ function resolveAsset(
     )
   }
 }
+
+function resolve(registry: Record<string, any> | undefined, name: string) {
+  return (
+    registry &&
+    (registry[name] ||
+      registry[camelize(name)] ||
+      registry[capitalize(camelize(name))])
+  )
+}