diff --git a/packages/compiler-core/src/transforms/transformExpression.ts b/packages/compiler-core/src/transforms/transformExpression.ts index a3a48be6..e4311ad4 100644 --- a/packages/compiler-core/src/transforms/transformExpression.ts +++ b/packages/compiler-core/src/transforms/transformExpression.ts @@ -24,7 +24,13 @@ import { walkIdentifiers } from '../babelUtils' import { advancePositionWithClone, isSimpleIdentifier } from '../utils' -import { isGloballyWhitelisted, makeMap, hasOwn, isString } from '@vue/shared' +import { + isGloballyWhitelisted, + makeMap, + hasOwn, + isString, + genPropsAccessExp +} from '@vue/shared' import { createCompilerError, ErrorCodes } from '../errors' import { Node, @@ -185,17 +191,17 @@ export function processExpression( } else if (type === BindingTypes.PROPS) { // use __props which is generated by compileScript so in ts mode // it gets correct type - return `__props.${raw}` + return genPropsAccessExp(raw) } else if (type === BindingTypes.PROPS_ALIASED) { // prop with a different local alias (from defineProps() destructure) - return `__props.${bindingMetadata.__propsAliases![raw]}` + return genPropsAccessExp(bindingMetadata.__propsAliases![raw]) } } else { if (type && type.startsWith('setup')) { // setup bindings in non-inline mode return `$setup.${raw}` } else if (type === BindingTypes.PROPS_ALIASED) { - return `$props.${bindingMetadata.__propsAliases![raw]}` + return `$props['${bindingMetadata.__propsAliases![raw]}']` } else if (type) { return `$${type}.${raw}` } diff --git a/packages/compiler-sfc/__tests__/__snapshots__/compileScriptPropsTransform.spec.ts.snap b/packages/compiler-sfc/__tests__/__snapshots__/compileScriptPropsTransform.spec.ts.snap index 8a735942..cfde6700 100644 --- a/packages/compiler-sfc/__tests__/__snapshots__/compileScriptPropsTransform.spec.ts.snap +++ b/packages/compiler-sfc/__tests__/__snapshots__/compileScriptPropsTransform.spec.ts.snap @@ -134,6 +134,25 @@ return () => {} }" `; +exports[`sfc props transform non-identifier prop names 1`] = ` +"import { toDisplayString as _toDisplayString } from \\"vue\\" + + +export default { + props: { 'foo.bar': Function }, + setup(__props) { + + + let x = __props[\\"foo.bar\\"] + +return (_ctx, _cache) => { + return _toDisplayString(__props[\\"foo.bar\\"]) +} +} + +}" +`; + exports[`sfc props transform rest spread 1`] = ` "import { createPropsRestProxy as _createPropsRestProxy } from 'vue' diff --git a/packages/compiler-sfc/__tests__/compileScriptPropsTransform.spec.ts b/packages/compiler-sfc/__tests__/compileScriptPropsTransform.spec.ts index 0dafc020..25fb4bed 100644 --- a/packages/compiler-sfc/__tests__/compileScriptPropsTransform.spec.ts +++ b/packages/compiler-sfc/__tests__/compileScriptPropsTransform.spec.ts @@ -127,6 +127,28 @@ describe('sfc props transform', () => { }) }) + // #5425 + test('non-identifier prop names', () => { + const { content, bindings } = compile(` + + + `) + expect(content).toMatch(`x = __props["foo.bar"]`) + expect(content).toMatch(`toDisplayString(__props["foo.bar"])`) + assertCode(content) + expect(bindings).toStrictEqual({ + x: BindingTypes.SETUP_LET, + 'foo.bar': BindingTypes.PROPS, + fooBar: BindingTypes.PROPS_ALIASED, + __propsAliases: { + fooBar: 'foo.bar' + } + }) + }) + test('rest spread', () => { const { content, bindings } = compile(`