wip: optimize binding access to known imported components

This commit is contained in:
Evan You 2020-11-10 18:06:38 -05:00
parent 4977526a2b
commit 4e8ef55237
4 changed files with 49 additions and 21 deletions

View File

@ -62,7 +62,7 @@ export type HoistTransform = (
) => void ) => void
export interface BindingMetadata { export interface BindingMetadata {
[key: string]: 'data' | 'props' | 'setup' | 'options' [key: string]: 'data' | 'props' | 'setup' | 'options' | 'component-import'
} }
interface SharedTransformCodegenOptions { interface SharedTransformCodegenOptions {

View File

@ -40,7 +40,8 @@ import {
TO_HANDLERS, TO_HANDLERS,
TELEPORT, TELEPORT,
KEEP_ALIVE, KEEP_ALIVE,
SUSPENSE SUSPENSE,
UNREF
} from '../runtimeHelpers' } from '../runtimeHelpers'
import { import {
getInnerRange, getInnerRange,
@ -53,6 +54,7 @@ import {
} from '../utils' } from '../utils'
import { buildSlots } from './vSlot' import { buildSlots } from './vSlot'
import { getStaticType } from './hoistStatic' import { getStaticType } from './hoistStatic'
import { BindingMetadata } from '../options'
// some directive transforms (e.g. v-model) may return a symbol for runtime // some directive transforms (e.g. v-model) may return a symbol for runtime
// import, which should be used instead of a resolveDirective call. // import, which should be used instead of a resolveDirective call.
@ -249,20 +251,33 @@ export function resolveComponentType(
} }
// 3. user component (from setup bindings) // 3. user component (from setup bindings)
let tagFromSetup = tag
const bindings = context.bindingMetadata const bindings = context.bindingMetadata
if ( if (bindings !== EMPTY_OBJ) {
bindings !== EMPTY_OBJ && const checkType = (type: BindingMetadata[string]) => {
(bindings[tagFromSetup] === 'setup' || let resolvedTag = tag
bindings[(tagFromSetup = camelize(tag))] === 'setup' || if (
bindings[(tagFromSetup = capitalize(camelize(tag)))] === 'setup') bindings[resolvedTag] === type ||
) { bindings[(resolvedTag = camelize(tag))] === type ||
return context.inline bindings[(resolvedTag = capitalize(camelize(tag)))] === type
? tagFromSetup ) {
: `$setup[${JSON.stringify(tagFromSetup)}]` 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.helper(RESOLVE_COMPONENT)
context.components.add(tag) context.components.add(tag)
return toValidAssetId(tag, `component`) return toValidAssetId(tag, `component`)

View File

@ -107,6 +107,8 @@ export function processExpression(
return `${inlinePropsIdentifier}.${raw}` return `${inlinePropsIdentifier}.${raw}`
} else if (type === 'setup') { } else if (type === 'setup') {
return `${context.helperString(UNREF)}(${raw})` return `${context.helperString(UNREF)}(${raw})`
} else if (type === 'component-import') {
return raw
} }
} }
// fallback to normal // fallback to normal

View File

@ -736,7 +736,7 @@ export function compileScript(
`\nexport ${hasAwait ? `async ` : ``}function setup(${args}) {\n` `\nexport ${hasAwait ? `async ` : ``}function setup(${args}) {\n`
) )
const exposedBindings = { ...userImports, ...setupBindings } const allBindings = { ...userImports, ...setupBindings }
// 9. inject `useCssVars` calls // 9. inject `useCssVars` calls
if (hasCssVars) { if (hasCssVars) {
@ -746,7 +746,7 @@ export function compileScript(
if (typeof vars === 'string') { if (typeof vars === 'string') {
s.prependRight( s.prependRight(
endOffset, endOffset,
`\n${genCssVarsCode(vars, !!style.scoped, exposedBindings)}` `\n${genCssVarsCode(vars, !!style.scoped, allBindings)}`
) )
} }
} }
@ -756,12 +756,23 @@ export function compileScript(
if (scriptAst) { if (scriptAst) {
Object.assign(bindingMetadata, analyzeScriptBindings(scriptAst)) Object.assign(bindingMetadata, analyzeScriptBindings(scriptAst))
} }
Object.keys(exposedBindings).forEach(key => { if (options.inlineTemplate) {
bindingMetadata[key] = 'setup' for (const [key, value] of Object.entries(userImports)) {
}) bindingMetadata[key] = value.endsWith('.vue')
Object.keys(typeDeclaredProps).forEach(key => { ? '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' bindingMetadata[key] = 'props'
}) }
Object.assign(bindingMetadata, analyzeScriptBindings(scriptSetupAst)) Object.assign(bindingMetadata, analyzeScriptBindings(scriptSetupAst))
// 11. generate return statement // 11. generate return statement
@ -799,7 +810,7 @@ export function compileScript(
} }
} else { } else {
// return bindings from setup // return bindings from setup
returned = `{ ${Object.keys(exposedBindings).join(', ')} }` returned = `{ ${Object.keys(allBindings).join(', ')} }`
} }
s.appendRight(endOffset, `\nreturn ${returned}\n}\n\n`) s.appendRight(endOffset, `\nreturn ${returned}\n}\n\n`)