}"
`;
+exports[`SFC compile <script setup> > inlineTemplate mode > destructure setup context for built-in properties > should alias __emit to $emit when defineEmits is used 1`] = `
+"import { openBlock as _openBlock, createElementBlock as _createElementBlock } from "vue"
+
+
+export default {
+ emits: ['click'],
+ setup(__props, { emit: __emit }) {
+ const $emit = __emit
+
+ const emit = __emit
+
+return (_ctx, _cache) => {
+ return (_openBlock(), _createElementBlock("div", {
+ onClick: _cache[0] || (_cache[0] = $event => ($emit('click')))
+ }))
+}
+}
+
+}"
+`;
+
+exports[`SFC compile <script setup> > inlineTemplate mode > destructure setup context for built-in properties > should alias __props to $props when $props is used 1`] = `
+"import { toDisplayString as _toDisplayString, openBlock as _openBlock, createElementBlock as _createElementBlock } from "vue"
+
+
+export default {
+ setup(__props) {
+ const $props = __props
+/* ... */
+return (_ctx, _cache) => {
+ return (_openBlock(), _createElementBlock("div", null, _toDisplayString($props), 1 /* TEXT */))
+}
+}
+
+}"
+`;
+
+exports[`SFC compile <script setup> > inlineTemplate mode > destructure setup context for built-in properties > should extract all built-in properties when they are used 1`] = `
+"import { toDisplayString as _toDisplayString, openBlock as _openBlock, createElementBlock as _createElementBlock } from "vue"
+
+
+export default {
+ setup(__props, { emit: $emit, attrs: $attrs, slots: $slots }) {
+ const $props = __props
+/* ... */
+return (_ctx, _cache) => {
+ return (_openBlock(), _createElementBlock("div", null, _toDisplayString($props) + _toDisplayString($slots) + _toDisplayString($emit) + _toDisplayString($attrs), 1 /* TEXT */))
+}
+}
+
+}"
+`;
+
+exports[`SFC compile <script setup> > inlineTemplate mode > destructure setup context for built-in properties > should extract attrs when $attrs is used 1`] = `
+"import { normalizeProps as _normalizeProps, guardReactiveProps as _guardReactiveProps, openBlock as _openBlock, createElementBlock as _createElementBlock } from "vue"
+
+
+export default {
+ setup(__props, { attrs: $attrs }) {
+/* ... */
+return (_ctx, _cache) => {
+ return (_openBlock(), _createElementBlock("div", _normalizeProps(_guardReactiveProps($attrs)), null, 16 /* FULL_PROPS */))
+}
+}
+
+}"
+`;
+
+exports[`SFC compile <script setup> > inlineTemplate mode > destructure setup context for built-in properties > should extract emit when $emit is used 1`] = `
+"import { openBlock as _openBlock, createElementBlock as _createElementBlock } from "vue"
+
+
+export default {
+ setup(__props, { emit: $emit }) {
+/* ... */
+return (_ctx, _cache) => {
+ return (_openBlock(), _createElementBlock("div", {
+ onClick: _cache[0] || (_cache[0] = $event => ($emit('click')))
+ }))
+}
+}
+
+}"
+`;
+
+exports[`SFC compile <script setup> > inlineTemplate mode > destructure setup context for built-in properties > should extract slots when $slots is used 1`] = `
+"import { resolveComponent as _resolveComponent, openBlock as _openBlock, createBlock as _createBlock } from "vue"
+
+
+export default {
+ setup(__props, { slots: $slots }) {
+/* ... */
+return (_ctx, _cache) => {
+ const _component_Comp = _resolveComponent("Comp")
+
+ return (_openBlock(), _createBlock(_component_Comp, {
+ foo: $slots.foo
+ }, null, 8 /* PROPS */, ["foo"]))
+}
+}
+
+}"
+`;
+
+exports[`SFC compile <script setup> > inlineTemplate mode > destructure setup context for built-in properties > should not extract built-in properties when neither is used 1`] = `
+"import { toDisplayString as _toDisplayString, openBlock as _openBlock, createElementBlock as _createElementBlock } from "vue"
+
+
+export default {
+ setup(__props) {
+/* ... */
+return (_ctx, _cache) => {
+ return (_openBlock(), _createElementBlock("div", null, _toDisplayString(_ctx.msg), 1 /* TEXT */))
+}
+}
+
+}"
+`;
+
+exports[`SFC compile <script setup> > inlineTemplate mode > destructure setup context for built-in properties > user-defined properties override > should handle mixed defineEmits and user-defined $emit 1`] = `
+"import { unref as _unref, openBlock as _openBlock, createElementBlock as _createElementBlock } from "vue"
+
+
+export default {
+ emits: ['click'],
+ setup(__props, { emit: __emit }) {
+
+ const emit = __emit
+ let $emit
+
+return (_ctx, _cache) => {
+ return (_openBlock(), _createElementBlock("div", {
+ onClick: _cache[0] || (_cache[0] = $event => (_unref($emit)('click')))
+ }, "click"))
+}
+}
+
+}"
+`;
+
+exports[`SFC compile <script setup> > inlineTemplate mode > destructure setup context for built-in properties > user-defined properties override > should not extract $attrs when user defines it 1`] = `
+"import { unref as _unref, normalizeProps as _normalizeProps, guardReactiveProps as _guardReactiveProps, openBlock as _openBlock, createElementBlock as _createElementBlock } from "vue"
+
+
+export default {
+ setup(__props) {
+let $attrs
+return (_ctx, _cache) => {
+ return (_openBlock(), _createElementBlock("div", _normalizeProps(_guardReactiveProps(_unref($attrs))), null, 16 /* FULL_PROPS */))
+}
+}
+
+}"
+`;
+
+exports[`SFC compile <script setup> > inlineTemplate mode > destructure setup context for built-in properties > user-defined properties override > should not extract $emit when user defines it 1`] = `
+"import { unref as _unref, openBlock as _openBlock, createElementBlock as _createElementBlock } from "vue"
+
+
+export default {
+ setup(__props) {
+let $emit
+return (_ctx, _cache) => {
+ return (_openBlock(), _createElementBlock("div", {
+ onClick: _cache[0] || (_cache[0] = $event => (_unref($emit)('click')))
+ }, "click"))
+}
+}
+
+}"
+`;
+
+exports[`SFC compile <script setup> > inlineTemplate mode > destructure setup context for built-in properties > user-defined properties override > should not extract $slots when user defines it 1`] = `
+"import { unref as _unref, resolveComponent as _resolveComponent, openBlock as _openBlock, createBlock as _createBlock } from "vue"
+
+
+export default {
+ setup(__props) {
+let $slots
+return (_ctx, _cache) => {
+ const _component_Comp = _resolveComponent("Comp")
+
+ return (_openBlock(), _createBlock(_component_Comp, {
+ foo: _unref($slots).foo
+ }, null, 8 /* PROPS */, ["foo"]))
+}
+}
+
+}"
+`;
+
+exports[`SFC compile <script setup> > inlineTemplate mode > destructure setup context for built-in properties > user-defined properties override > should not generate $props alias when user defines it 1`] = `
+"import { unref as _unref, toDisplayString as _toDisplayString, openBlock as _openBlock, createElementBlock as _createElementBlock } from "vue"
+
+
+export default {
+ setup(__props) {
+let $props
+return (_ctx, _cache) => {
+ return (_openBlock(), _createElementBlock("div", null, _toDisplayString(_unref($props).msg), 1 /* TEXT */))
+}
+}
+
+}"
+`;
+
+exports[`SFC compile <script setup> > inlineTemplate mode > destructure setup context for built-in properties > user-defined properties override > should only extract non-user-defined properties 1`] = `
+"import { unref as _unref, toDisplayString as _toDisplayString, openBlock as _openBlock, createElementBlock as _createElementBlock } from "vue"
+
+
+export default {
+ setup(__props, { emit: $emit, slots: $slots }) {
+ const $props = __props
+let $attrs
+return (_ctx, _cache) => {
+ return (_openBlock(), _createElementBlock("div", null, _toDisplayString(_unref($attrs)) + _toDisplayString($slots) + _toDisplayString($emit) + _toDisplayString($props), 1 /* TEXT */))
+}
+}
+
+}"
+`;
+
+exports[`SFC compile <script setup> > inlineTemplate mode > destructuring setup context for built-in properties > should alias __emit to $emit when defineEmits is used 1`] = `
+"import { openBlock as _openBlock, createElementBlock as _createElementBlock } from "vue"
+
+
+export default {
+ emits: ['click'],
+ setup(__props, { emit: __emit }) {
+ const $emit = __emit
+
+ const emit = __emit
+
+return (_ctx, _cache) => {
+ return (_openBlock(), _createElementBlock("div", {
+ onClick: _cache[0] || (_cache[0] = $event => ($emit('click')))
+ }))
+}
+}
+
+}"
+`;
+
+exports[`SFC compile <script setup> > inlineTemplate mode > destructuring setup context for built-in properties > should alias __props to $props when $props is used 1`] = `
+"import { toDisplayString as _toDisplayString, openBlock as _openBlock, createElementBlock as _createElementBlock } from "vue"
+
+
+export default {
+ setup(__props) {
+ const $props = __props
+/* ... */
+return (_ctx, _cache) => {
+ return (_openBlock(), _createElementBlock("div", null, _toDisplayString($props), 1 /* TEXT */))
+}
+}
+
+}"
+`;
+
+exports[`SFC compile <script setup> > inlineTemplate mode > destructuring setup context for built-in properties > should extract all built-in properties when they are used 1`] = `
+"import { toDisplayString as _toDisplayString, openBlock as _openBlock, createElementBlock as _createElementBlock } from "vue"
+
+
+export default {
+ setup(__props, { emit: $emit, attrs: $attrs, slots: $slots }) {
+ const $props = __props
+/* ... */
+return (_ctx, _cache) => {
+ return (_openBlock(), _createElementBlock("div", null, _toDisplayString($props) + _toDisplayString($slots) + _toDisplayString($emit) + _toDisplayString($attrs), 1 /* TEXT */))
+}
+}
+
+}"
+`;
+
+exports[`SFC compile <script setup> > inlineTemplate mode > destructuring setup context for built-in properties > should extract attrs when $attrs is used 1`] = `
+"import { normalizeProps as _normalizeProps, guardReactiveProps as _guardReactiveProps, openBlock as _openBlock, createElementBlock as _createElementBlock } from "vue"
+
+
+export default {
+ setup(__props, { attrs: $attrs }) {
+/* ... */
+return (_ctx, _cache) => {
+ return (_openBlock(), _createElementBlock("div", _normalizeProps(_guardReactiveProps($attrs)), null, 16 /* FULL_PROPS */))
+}
+}
+
+}"
+`;
+
+exports[`SFC compile <script setup> > inlineTemplate mode > destructuring setup context for built-in properties > should extract emit when $emit is used 1`] = `
+"import { openBlock as _openBlock, createElementBlock as _createElementBlock } from "vue"
+
+
+export default {
+ setup(__props, { emit: $emit }) {
+/* ... */
+return (_ctx, _cache) => {
+ return (_openBlock(), _createElementBlock("div", {
+ onClick: _cache[0] || (_cache[0] = $event => ($emit('click')))
+ }))
+}
+}
+
+}"
+`;
+
+exports[`SFC compile <script setup> > inlineTemplate mode > destructuring setup context for built-in properties > should extract slots when $slots is used 1`] = `
+"import { resolveComponent as _resolveComponent, openBlock as _openBlock, createBlock as _createBlock } from "vue"
+
+
+export default {
+ setup(__props, { slots: $slots }) {
+/* ... */
+return (_ctx, _cache) => {
+ const _component_Comp = _resolveComponent("Comp")
+
+ return (_openBlock(), _createBlock(_component_Comp, {
+ foo: $slots.foo
+ }, null, 8 /* PROPS */, ["foo"]))
+}
+}
+
+}"
+`;
+
+exports[`SFC compile <script setup> > inlineTemplate mode > destructuring setup context for built-in properties > should not extract built-in properties when neither is used 1`] = `
+"import { toDisplayString as _toDisplayString, openBlock as _openBlock, createElementBlock as _createElementBlock } from "vue"
+
+
+export default {
+ setup(__props) {
+/* ... */
+return (_ctx, _cache) => {
+ return (_openBlock(), _createElementBlock("div", null, _toDisplayString(_ctx.msg), 1 /* TEXT */))
+}
+}
+
+}"
+`;
+
+exports[`SFC compile <script setup> > inlineTemplate mode > destructuring setup context for built-in properties > user-defined properties override > should handle mixed defineEmits and user-defined $emit 1`] = `
+"import { unref as _unref, openBlock as _openBlock, createElementBlock as _createElementBlock } from "vue"
+
+
+export default {
+ emits: ['click'],
+ setup(__props, { emit: __emit }) {
+
+ const emit = __emit
+ let $emit
+
+return (_ctx, _cache) => {
+ return (_openBlock(), _createElementBlock("div", {
+ onClick: _cache[0] || (_cache[0] = $event => (_unref($emit)('click')))
+ }, "click"))
+}
+}
+
+}"
+`;
+
+exports[`SFC compile <script setup> > inlineTemplate mode > destructuring setup context for built-in properties > user-defined properties override > should not extract $attrs when user defines it 1`] = `
+"import { unref as _unref, normalizeProps as _normalizeProps, guardReactiveProps as _guardReactiveProps, openBlock as _openBlock, createElementBlock as _createElementBlock } from "vue"
+
+
+export default {
+ setup(__props) {
+let $attrs
+return (_ctx, _cache) => {
+ return (_openBlock(), _createElementBlock("div", _normalizeProps(_guardReactiveProps(_unref($attrs))), null, 16 /* FULL_PROPS */))
+}
+}
+
+}"
+`;
+
+exports[`SFC compile <script setup> > inlineTemplate mode > destructuring setup context for built-in properties > user-defined properties override > should not extract $emit when user defines it 1`] = `
+"import { unref as _unref, openBlock as _openBlock, createElementBlock as _createElementBlock } from "vue"
+
+
+export default {
+ setup(__props) {
+let $emit
+return (_ctx, _cache) => {
+ return (_openBlock(), _createElementBlock("div", {
+ onClick: _cache[0] || (_cache[0] = $event => (_unref($emit)('click')))
+ }, "click"))
+}
+}
+
+}"
+`;
+
+exports[`SFC compile <script setup> > inlineTemplate mode > destructuring setup context for built-in properties > user-defined properties override > should not extract $slots when user defines it 1`] = `
+"import { unref as _unref, resolveComponent as _resolveComponent, openBlock as _openBlock, createBlock as _createBlock } from "vue"
+
+
+export default {
+ setup(__props) {
+let $slots
+return (_ctx, _cache) => {
+ const _component_Comp = _resolveComponent("Comp")
+
+ return (_openBlock(), _createBlock(_component_Comp, {
+ foo: _unref($slots).foo
+ }, null, 8 /* PROPS */, ["foo"]))
+}
+}
+
+}"
+`;
+
+exports[`SFC compile <script setup> > inlineTemplate mode > destructuring setup context for built-in properties > user-defined properties override > should not generate $props alias when user defines it 1`] = `
+"import { unref as _unref, toDisplayString as _toDisplayString, openBlock as _openBlock, createElementBlock as _createElementBlock } from "vue"
+
+
+export default {
+ setup(__props) {
+let $props
+return (_ctx, _cache) => {
+ return (_openBlock(), _createElementBlock("div", null, _toDisplayString(_unref($props).msg), 1 /* TEXT */))
+}
+}
+
+}"
+`;
+
+exports[`SFC compile <script setup> > inlineTemplate mode > destructuring setup context for built-in properties > user-defined properties override > should only extract non-user-defined properties 1`] = `
+"import { unref as _unref, toDisplayString as _toDisplayString, openBlock as _openBlock, createElementBlock as _createElementBlock } from "vue"
+
+
+export default {
+ setup(__props, { emit: $emit, slots: $slots }) {
+ const $props = __props
+let $attrs
+return (_ctx, _cache) => {
+ return (_openBlock(), _createElementBlock("div", null, _toDisplayString(_unref($attrs)) + _toDisplayString($slots) + _toDisplayString($emit) + _toDisplayString($props), 1 /* TEXT */))
+}
+}
+
+}"
+`;
+
exports[`SFC compile <script setup> > inlineTemplate mode > referencing scope components and directives 1`] = `
"import { unref as _unref, createElementVNode as _createElementVNode, withDirectives as _withDirectives, createVNode as _createVNode, Fragment as _Fragment, openBlock as _openBlock, createElementBlock as _createElementBlock } from "vue"
consumer.originalPositionFor(getPositionInCode(content, 'Error')),
).toMatchObject(getPositionInCode(source, `Error`))
})
+
+ describe('destructure setup context for built-in properties', () => {
+ const theCompile = (template: string, setup = '/* ... */') =>
+ compile(
+ `<script setup>${setup}</script>\n<template>${template}</template>`,
+ { inlineTemplate: true },
+ )
+
+ test('should extract attrs when $attrs is used', () => {
+ let { content } = theCompile('<div v-bind="$attrs"></div>')
+ expect(content).toMatch('setup(__props, { attrs: $attrs })')
+ expect(content).not.toMatch('slots: $slots')
+ expect(content).not.toMatch('emit: $emit')
+ expect(content).not.toMatch('const $props = __props')
+ assertCode(content)
+ })
+
+ test('should extract slots when $slots is used', () => {
+ let { content } = theCompile('<Comp :foo="$slots.foo"></Comp>')
+ expect(content).toMatch('setup(__props, { slots: $slots })')
+ assertCode(content)
+ })
+
+ test('should alias __props to $props when $props is used', () => {
+ let { content } = theCompile('<div>{{ $props }}</div>')
+ expect(content).toMatch('setup(__props)')
+ expect(content).toMatch('const $props = __props')
+ assertCode(content)
+ })
+
+ test('should extract emit when $emit is used', () => {
+ let { content } = theCompile(`<div @click="$emit('click')"></div>`)
+ expect(content).toMatch('setup(__props, { emit: $emit })')
+ expect(content).not.toMatch('const $emit = __emit')
+ assertCode(content)
+ })
+
+ test('should alias __emit to $emit when defineEmits is used', () => {
+ let { content } = compile(
+ `
+ <script setup>
+ const emit = defineEmits(['click'])
+ </script>
+ <template>
+ <div @click="$emit('click')"></div>
+ </template>
+ `,
+ { inlineTemplate: true },
+ )
+ expect(content).toMatch('setup(__props, { emit: __emit })')
+ expect(content).toMatch('const $emit = __emit')
+ expect(content).toMatch('const emit = __emit')
+ assertCode(content)
+ })
+
+ test('should extract all built-in properties when they are used', () => {
+ let { content } = theCompile(
+ '<div>{{ $props }}{{ $slots }}{{ $emit }}{{ $attrs }}</div>',
+ )
+ expect(content).toMatch(
+ 'setup(__props, { emit: $emit, attrs: $attrs, slots: $slots })',
+ )
+ expect(content).toMatch('const $props = __props')
+ assertCode(content)
+ })
+
+ test('should not extract built-in properties when neither is used', () => {
+ let { content } = theCompile('<div>{{ msg }}</div>')
+ expect(content).toMatch('setup(__props)')
+ expect(content).not.toMatch('attrs: $attrs')
+ expect(content).not.toMatch('slots: $slots')
+ expect(content).not.toMatch('emit: $emit')
+ expect(content).not.toMatch('props: $props')
+ assertCode(content)
+ })
+
+ describe('user-defined properties override', () => {
+ test('should not extract $attrs when user defines it', () => {
+ let { content } = theCompile(
+ '<div v-bind="$attrs"></div>',
+ 'let $attrs',
+ )
+ expect(content).toMatch('setup(__props)')
+ expect(content).not.toMatch('attrs: $attrs')
+ assertCode(content)
+ })
+
+ test('should not extract $slots when user defines it', () => {
+ let { content } = theCompile(
+ '<Comp :foo="$slots.foo"></Comp>',
+ 'let $slots',
+ )
+ expect(content).toMatch('setup(__props)')
+ expect(content).not.toMatch('slots: $slots')
+ assertCode(content)
+ })
+
+ test('should not extract $emit when user defines it', () => {
+ let { content } = theCompile(
+ `<div @click="$emit('click')">click</div>`,
+ 'let $emit',
+ )
+ expect(content).toMatch('setup(__props)')
+ expect(content).not.toMatch('emit: $emit')
+ assertCode(content)
+ })
+
+ test('should not generate $props alias when user defines it', () => {
+ let { content } = theCompile(
+ '<div>{{ $props.msg }}</div>',
+ 'let $props',
+ )
+ expect(content).toMatch('setup(__props)')
+ expect(content).not.toMatch('const $props = __props')
+ assertCode(content)
+ })
+
+ test('should only extract non-user-defined properties', () => {
+ let { content } = theCompile(
+ '<div>{{ $attrs }}{{ $slots }}{{ $emit }}{{ $props }}</div>',
+ 'let $attrs',
+ )
+ expect(content).toMatch(
+ 'setup(__props, { emit: $emit, slots: $slots })',
+ )
+ expect(content).not.toMatch('attrs: $attrs')
+ expect(content).toMatch('const $props = __props')
+ assertCode(content)
+ })
+
+ test('should handle mixed defineEmits and user-defined $emit', () => {
+ let { content } = theCompile(
+ `<div @click="$emit('click')">click</div>`,
+ `
+ const emit = defineEmits(['click'])
+ let $emit
+ `,
+ )
+ expect(content).toMatch('setup(__props, { emit: __emit })')
+ expect(content).toMatch('const emit = __emit')
+ expect(content).not.toMatch('const $emit = __emit')
+ assertCode(content)
+ })
+ })
+ })
})
describe('with TypeScript', () => {
import { DEFINE_MODEL, processDefineModel } from './script/defineModel'
import { getImportedName, isCallOf, isLiteralNode } from './script/utils'
import { analyzeScriptBindings } from './script/analyzeScriptBindings'
-import { isImportUsed } from './script/importUsageCheck'
+import { isUsedInTemplate } from './script/importUsageCheck'
import { processAwait } from './script/topLevelAwait'
export interface SFCScriptCompileOptions {
const scriptSetupLang = scriptSetup && scriptSetup.lang
const vapor = sfc.vapor || options.vapor
const ssr = options.templateOptions?.ssr
+ const setupPreambleLines = [] as string[]
if (!scriptSetup) {
if (!script) {
) {
// template usage check is only needed in non-inline mode, so we can skip
// the work if inlineTemplate is true.
- let isUsedInTemplate = needTemplateUsageCheck
+ let isImportUsed = needTemplateUsageCheck
if (
needTemplateUsageCheck &&
ctx.isTS &&
!sfc.template.src &&
!sfc.template.lang
) {
- isUsedInTemplate = isImportUsed(local, sfc)
+ isImportUsed = isUsedInTemplate(local, sfc)
}
ctx.userImports[local] = {
local,
source,
isFromSetup,
- isUsedInTemplate,
+ isUsedInTemplate: isImportUsed,
}
}
})
}
+ function buildDestructureElements() {
+ if (!sfc.template || !sfc.template.ast) return
+
+ const builtins = {
+ $props: {
+ bindingType: BindingTypes.SETUP_REACTIVE_CONST,
+ setup: () => setupPreambleLines.push(`const $props = __props`),
+ },
+ $emit: {
+ bindingType: BindingTypes.SETUP_CONST,
+ setup: () =>
+ ctx.emitDecl
+ ? setupPreambleLines.push(`const $emit = __emit`)
+ : destructureElements.push('emit: $emit'),
+ },
+ $attrs: {
+ bindingType: BindingTypes.SETUP_REACTIVE_CONST,
+ setup: () => destructureElements.push('attrs: $attrs'),
+ },
+ $slots: {
+ bindingType: BindingTypes.SETUP_REACTIVE_CONST,
+ setup: () => destructureElements.push('slots: $slots'),
+ },
+ }
+
+ for (const [name, config] of Object.entries(builtins)) {
+ if (isUsedInTemplate(name, sfc) && !ctx.bindingMetadata[name]) {
+ config.setup()
+ ctx.bindingMetadata[name] = config.bindingType
+ }
+ }
+ }
+
const scriptAst = ctx.scriptAst
const scriptSetupAst = ctx.scriptSetupAst!
+ const inlineMode = options.inlineTemplate
// 1.1 walk import declarations of <script>
if (scriptAst) {
(specifier.type === 'ImportSpecifier' &&
specifier.importKind === 'type'),
false,
- !options.inlineTemplate,
+ !inlineMode,
)
}
}
(specifier.type === 'ImportSpecifier' &&
specifier.importKind === 'type'),
true,
- !options.inlineTemplate,
+ !inlineMode,
)
}
}
}
const destructureElements =
- ctx.hasDefineExposeCall || !options.inlineTemplate
- ? [`expose: __expose`]
- : []
+ ctx.hasDefineExposeCall || !inlineMode ? [`expose: __expose`] : []
if (ctx.emitDecl) {
destructureElements.push(`emit: __emit`)
}
+
+ // destructure built-in properties (e.g. $emit, $attrs, $slots)
+ if (inlineMode) {
+ buildDestructureElements()
+ }
+
if (destructureElements.length) {
args += `, { ${destructureElements.join(', ')} }`
}
let templateMap
// 9. generate return statement
let returned
- if (
- !options.inlineTemplate ||
- (!sfc.template && ctx.hasDefaultExportRender)
- ) {
+ if (!inlineMode || (!sfc.template && ctx.hasDefaultExportRender)) {
// non-inline mode, or has manual render in normal <script>
// return bindings from script and script setup
const allBindings: Record<string, any> = {
}
}
- if (!options.inlineTemplate && !__TEST__) {
+ if (!inlineMode && !__TEST__) {
// in non-inline mode, the `__isScriptSetup: true` flag is used by
// componentPublicInstance proxy to allow properties that start with $ or _
ctx.s.appendRight(
// <script setup> components are closed by default. If the user did not
// explicitly call `defineExpose`, call expose() with no args.
- const exposeCall =
- ctx.hasDefineExposeCall || options.inlineTemplate ? `` : ` __expose();\n`
+ if (!ctx.hasDefineExposeCall && !inlineMode)
+ setupPreambleLines.push(`__expose();`)
+
+ const setupPreamble = setupPreambleLines.length
+ ? ` ${setupPreambleLines.join('\n ')}\n`
+ : ''
// wrap setup code with function.
if (ctx.isTS) {
// for TS, make sure the exported type is still valid type with
vapor && !ssr ? `defineVaporComponent` : `defineComponent`,
)}({${def}${runtimeOptions}\n ${
hasAwait ? `async ` : ``
- }setup(${args}) {\n${exposeCall}`,
+ }setup(${args}) {\n${setupPreamble}`,
)
ctx.s.appendRight(endOffset, `})`)
} else {
`\n${genDefaultAs} /*@__PURE__*/Object.assign(${
defaultExport ? `${normalScriptDefaultVar}, ` : ''
}${definedOptions ? `${definedOptions}, ` : ''}{${runtimeOptions}\n ` +
- `${hasAwait ? `async ` : ``}setup(${args}) {\n${exposeCall}`,
+ `${hasAwait ? `async ` : ``}setup(${args}) {\n${setupPreamble}`,
)
ctx.s.appendRight(endOffset, `})`)
} else {
ctx.s.prependLeft(
startOffset,
`\n${genDefaultAs} {${runtimeOptions}\n ` +
- `${hasAwait ? `async ` : ``}setup(${args}) {\n${exposeCall}`,
+ `${hasAwait ? `async ` : ``}setup(${args}) {\n${setupPreamble}`,
)
ctx.s.appendRight(endOffset, `}`)
}