]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
wip: optimize binding access to known imported components
authorEvan You <yyx990803@gmail.com>
Tue, 10 Nov 2020 23:06:38 +0000 (18:06 -0500)
committerEvan You <yyx990803@gmail.com>
Tue, 10 Nov 2020 23:06:38 +0000 (18:06 -0500)
packages/compiler-core/src/options.ts
packages/compiler-core/src/transforms/transformElement.ts
packages/compiler-core/src/transforms/transformExpression.ts
packages/compiler-sfc/src/compileScript.ts

index b0af0cefabe0b30b4fd59049e68bd169c774ff8c..5f0f06dbea4b692f07ed33cdf9e67c77dd86efad 100644 (file)
@@ -62,7 +62,7 @@ export type HoistTransform = (
 ) => void
 
 export interface BindingMetadata {
-  [key: string]: 'data' | 'props' | 'setup' | 'options'
+  [key: string]: 'data' | 'props' | 'setup' | 'options' | 'component-import'
 }
 
 interface SharedTransformCodegenOptions {
index f0e8d7cbbc4e22c64ac100bfa1c3976dcaf2049e..1025e602f49d2a73e7c4a68dcd2cbcb18a6c4454 100644 (file)
@@ -40,7 +40,8 @@ import {
   TO_HANDLERS,
   TELEPORT,
   KEEP_ALIVE,
-  SUSPENSE
+  SUSPENSE,
+  UNREF
 } from '../runtimeHelpers'
 import {
   getInnerRange,
@@ -53,6 +54,7 @@ import {
 } from '../utils'
 import { buildSlots } from './vSlot'
 import { getStaticType } from './hoistStatic'
+import { BindingMetadata } from '../options'
 
 // some directive transforms (e.g. v-model) may return a symbol for runtime
 // import, which should be used instead of a resolveDirective call.
@@ -249,20 +251,33 @@ export function resolveComponentType(
   }
 
   // 3. user component (from setup bindings)
-  let tagFromSetup = tag
   const bindings = context.bindingMetadata
-  if (
-    bindings !== EMPTY_OBJ &&
-    (bindings[tagFromSetup] === 'setup' ||
-      bindings[(tagFromSetup = camelize(tag))] === 'setup' ||
-      bindings[(tagFromSetup = capitalize(camelize(tag)))] === 'setup')
-  ) {
-    return context.inline
-      ? tagFromSetup
-      : `$setup[${JSON.stringify(tagFromSetup)}]`
+  if (bindings !== EMPTY_OBJ) {
+    const checkType = (type: BindingMetadata[string]) => {
+      let resolvedTag = tag
+      if (
+        bindings[resolvedTag] === type ||
+        bindings[(resolvedTag = camelize(tag))] === type ||
+        bindings[(resolvedTag = capitalize(camelize(tag)))] === type
+      ) {
+        return resolvedTag
+      }
+    }
+    const tagFromSetup = checkType('setup')
+    if (tagFromSetup) {
+      return context.inline
+        ? // setup scope bindings may be refs so they need to be unrefed
+          `${context.helperString(UNREF)}(${tagFromSetup})`
+        : `$setup[${JSON.stringify(tagFromSetup)}]`
+    }
+    const tagFromImport = checkType('component-import')
+    if (tagFromImport) {
+      // imports can be used as-is
+      return tagFromImport
+    }
   }
 
-  // 5. user component (resolve)
+  // 4. user component (resolve)
   context.helper(RESOLVE_COMPONENT)
   context.components.add(tag)
   return toValidAssetId(tag, `component`)
index 7552177c6aa361c49ac3a0a056c79964db387605..52a35538e9ce2db1803f8edbf79a2c5505f0de6b 100644 (file)
@@ -107,6 +107,8 @@ export function processExpression(
         return `${inlinePropsIdentifier}.${raw}`
       } else if (type === 'setup') {
         return `${context.helperString(UNREF)}(${raw})`
+      } else if (type === 'component-import') {
+        return raw
       }
     }
     // fallback to normal
index ab5aa43ae55a3b4092e87570c12b4f659a7a746c..085839415ff7769b3912a3675d2e2e1a861992cc 100644 (file)
@@ -736,7 +736,7 @@ export function compileScript(
     `\nexport ${hasAwait ? `async ` : ``}function setup(${args}) {\n`
   )
 
-  const exposedBindings = { ...userImports, ...setupBindings }
+  const allBindings = { ...userImports, ...setupBindings }
 
   // 9. inject `useCssVars` calls
   if (hasCssVars) {
@@ -746,7 +746,7 @@ export function compileScript(
       if (typeof vars === 'string') {
         s.prependRight(
           endOffset,
-          `\n${genCssVarsCode(vars, !!style.scoped, exposedBindings)}`
+          `\n${genCssVarsCode(vars, !!style.scoped, allBindings)}`
         )
       }
     }
@@ -756,12 +756,23 @@ export function compileScript(
   if (scriptAst) {
     Object.assign(bindingMetadata, analyzeScriptBindings(scriptAst))
   }
-  Object.keys(exposedBindings).forEach(key => {
-    bindingMetadata[key] = 'setup'
-  })
-  Object.keys(typeDeclaredProps).forEach(key => {
+  if (options.inlineTemplate) {
+    for (const [key, value] of Object.entries(userImports)) {
+      bindingMetadata[key] = value.endsWith('.vue')
+        ? 'component-import'
+        : 'setup'
+    }
+    for (const key in setupBindings) {
+      bindingMetadata[key] = 'setup'
+    }
+  } else {
+    for (const key in allBindings) {
+      bindingMetadata[key] = 'setup'
+    }
+  }
+  for (const key in typeDeclaredProps) {
     bindingMetadata[key] = 'props'
-  })
+  }
   Object.assign(bindingMetadata, analyzeScriptBindings(scriptSetupAst))
 
   // 11. generate return statement
@@ -799,7 +810,7 @@ export function compileScript(
     }
   } else {
     // return bindings from setup
-    returned = `{ ${Object.keys(exposedBindings).join(', ')} }`
+    returned = `{ ${Object.keys(allBindings).join(', ')} }`
   }
   s.appendRight(endOffset, `\nreturn ${returned}\n}\n\n`)