fix(compiler-sfc): properly handle shorthand property in template expressions

fix #12566
This commit is contained in:
Evan You 2022-06-21 09:41:30 +08:00
parent de03f69cd6
commit 9b9f2bf1c8
2 changed files with 19 additions and 20 deletions

View File

@ -1,7 +1,7 @@
import MagicString from 'magic-string'
import { parseExpression, ParserOptions, ParserPlugin } from '@babel/parser'
import { makeMap } from 'shared/util'
import { walkIdentifiers } from './babelUtils'
import { isStaticProperty, walkIdentifiers } from './babelUtils'
import { BindingMetadata } from './types'
const doNotPrefix = makeMap(
@ -39,18 +39,28 @@ export function prefixIdentifiers(
walkIdentifiers(
ast,
ident => {
(ident, parent) => {
const { name } = ident
if (doNotPrefix(name)) {
return
}
if (!isScriptSetup) {
s.prependRight(ident.start!, '_vm.')
return
let prefix = `_vm.`
if (isScriptSetup) {
const type = bindings[name]
if (type && type.startsWith('setup')) {
prefix = `_setup.`
}
}
s.overwrite(ident.start!, ident.end!, rewriteIdentifier(name, bindings))
if (isStaticProperty(parent) && parent.shorthand) {
// property shorthand like { foo }, we need to add the key since
// we rewrite the value
// { foo } -> { foo: _vm.foo }
s.appendLeft(ident.end!, `: ${prefix}${name}`)
} else {
s.prependRight(ident.start!, prefix)
}
},
node => {
if (node.type === 'WithStatement') {
@ -70,15 +80,3 @@ export function prefixIdentifiers(
return s.toString()
}
export function rewriteIdentifier(
name: string,
bindings: BindingMetadata
): string {
const type = bindings[name]
if (type && type.startsWith('setup')) {
return `_setup.${name}`
} else {
return `_vm.${name}`
}
}

View File

@ -7,7 +7,7 @@ const toFn = (source: string) => `function render(){${source}\n}`
it('should work', () => {
const { render } = compile(`<div id="app">
<div>{{ foo }}</div>
<div :style="{ color }">{{ foo }}</div>
<p v-for="i in list">{{ i }}</p>
<foo inline-template>
<div>{{ bar }}</div>
@ -22,6 +22,7 @@ it('should work', () => {
expect(result).not.toMatch(`_vm._c`)
expect(result).toMatch(`_vm.foo`)
expect(result).toMatch(`_vm.list`)
expect(result).toMatch(`{ color: _vm.color }`)
expect(result).not.toMatch(`_vm.i`)
expect(result).not.toMatch(`with (this)`)
@ -33,7 +34,7 @@ it('should work', () => {
\\"div\\",
{ attrs: { id: \\"app\\" } },
[
_c(\\"div\\", [_vm._v(_vm._s(_vm.foo))]),
_c(\\"div\\", { style: { color: _vm.color } }, [_vm._v(_vm._s(_vm.foo))]),
_vm._v(\\" \\"),
_vm._l(_vm.list, function (i) {
return _c(\\"p\\", [_vm._v(_vm._s(i))])