fix(compiler-sfc): named imports from .vue file should not be treated as constant

fix #2699
This commit is contained in:
Evan You 2020-12-01 11:52:29 -05:00
parent f2b0a8e81d
commit 085bbd5fe0
3 changed files with 19 additions and 10 deletions

View File

@ -195,10 +195,10 @@ return { ref }
`; `;
exports[`SFC compile <script setup> inlineTemplate mode avoid unref() when necessary 1`] = ` exports[`SFC compile <script setup> inlineTemplate mode avoid unref() when necessary 1`] = `
"import { createVNode as _createVNode, toDisplayString as _toDisplayString, unref as _unref, Fragment as _Fragment, openBlock as _openBlock, createBlock as _createBlock } from \\"vue\\" "import { unref as _unref, toDisplayString as _toDisplayString, createTextVNode as _createTextVNode, withCtx as _withCtx, createVNode as _createVNode, Fragment as _Fragment, openBlock as _openBlock, createBlock as _createBlock } from \\"vue\\"
import { ref } from 'vue' import { ref } from 'vue'
import Foo from './Foo.vue' import Foo, { bar } from './Foo.vue'
import other from './util' import other from './util'
export default { export default {
@ -213,7 +213,12 @@ export default {
return (_ctx, _cache) => { return (_ctx, _cache) => {
return (_openBlock(), _createBlock(_Fragment, null, [ return (_openBlock(), _createBlock(_Fragment, null, [
_createVNode(Foo), _createVNode(Foo, null, {
default: _withCtx(() => [
_createTextVNode(_toDisplayString(_unref(bar)), 1 /* TEXT */)
]),
_: 1 /* STABLE */
}),
_createVNode(\\"div\\", { onClick: fn }, _toDisplayString(count.value) + \\" \\" + _toDisplayString(constant) + \\" \\" + _toDisplayString(_unref(maybe)) + \\" \\" + _toDisplayString(_unref(lett)) + \\" \\" + _toDisplayString(_unref(other)), 1 /* TEXT */) _createVNode(\\"div\\", { onClick: fn }, _toDisplayString(count.value) + \\" \\" + _toDisplayString(constant) + \\" \\" + _toDisplayString(_unref(maybe)) + \\" \\" + _toDisplayString(_unref(lett)) + \\" \\" + _toDisplayString(_unref(other)), 1 /* TEXT */)
], 64 /* STABLE_FRAGMENT */)) ], 64 /* STABLE_FRAGMENT */))
} }

View File

@ -217,7 +217,7 @@ const myEmit = defineEmit(['foo', 'bar'])
const { content } = compile( const { content } = compile(
`<script setup> `<script setup>
import { ref } from 'vue' import { ref } from 'vue'
import Foo from './Foo.vue' import Foo, { bar } from './Foo.vue'
import other from './util' import other from './util'
const count = ref(0) const count = ref(0)
const constant = {} const constant = {}
@ -226,14 +226,16 @@ const myEmit = defineEmit(['foo', 'bar'])
function fn() {} function fn() {}
</script> </script>
<template> <template>
<Foo/> <Foo>{{ bar }}</Foo>
<div @click="fn">{{ count }} {{ constant }} {{ maybe }} {{ lett }} {{ other }}</div> <div @click="fn">{{ count }} {{ constant }} {{ maybe }} {{ lett }} {{ other }}</div>
</template> </template>
`, `,
{ inlineTemplate: true } { inlineTemplate: true }
) )
// no need to unref vue component import // no need to unref vue component import
expect(content).toMatch(`createVNode(Foo)`) expect(content).toMatch(`createVNode(Foo,`)
// #2699 should unref named imports from .vue
expect(content).toMatch(`unref(bar)`)
// should unref other imports // should unref other imports
expect(content).toMatch(`unref(other)`) expect(content).toMatch(`unref(other)`)
// no need to unref constant literals // no need to unref constant literals

View File

@ -168,7 +168,7 @@ export function compileScript(
string, string,
{ {
isType: boolean isType: boolean
imported: string | null imported: string
source: string source: string
} }
> = Object.create(null) > = Object.create(null)
@ -246,7 +246,7 @@ export function compileScript(
} }
userImports[local] = { userImports[local] = {
isType, isType,
imported: imported || null, imported: imported || 'default',
source source
} }
} }
@ -807,10 +807,12 @@ export function compileScript(
for (const key in typeDeclaredProps) { for (const key in typeDeclaredProps) {
bindingMetadata[key] = BindingTypes.PROPS bindingMetadata[key] = BindingTypes.PROPS
} }
for (const [key, { isType, source }] of Object.entries(userImports)) { for (const [key, { isType, imported, source }] of Object.entries(
userImports
)) {
if (isType) continue if (isType) continue
bindingMetadata[key] = bindingMetadata[key] =
source.endsWith('.vue') || source === 'vue' (imported === 'default' && source.endsWith('.vue')) || source === 'vue'
? BindingTypes.SETUP_CONST ? BindingTypes.SETUP_CONST
: BindingTypes.SETUP_MAYBE_REF : BindingTypes.SETUP_MAYBE_REF
} }