fix(custom-element): correctly handle number type props in prod (#8989)

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
This commit is contained in:
白雾三语 2023-12-06 15:16:16 +08:00 committed by GitHub
parent af5df91e95
commit d74d364d62
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 115 additions and 0 deletions

View File

@ -18,6 +18,66 @@ return { props, bar }
}" }"
`; `;
exports[`defineProps > custom element retains the props type & default value & production mode 1`] = `
"import { defineComponent as _defineComponent } from 'vue'
interface Props {
foo?: number;
}
export default /*#__PURE__*/_defineComponent({
__name: 'app.ce',
props: {
foo: { default: 5.5, type: Number }
},
setup(__props: any, { expose: __expose }) {
__expose();
const props = __props;
return { props }
}
})"
`;
exports[`defineProps > custom element retains the props type & production mode 1`] = `
"import { defineComponent as _defineComponent } from 'vue'
export default /*#__PURE__*/_defineComponent({
__name: 'app.ce',
props: {
foo: {type: Number}
},
setup(__props: any, { expose: __expose }) {
__expose();
const props = __props
return { props }
}
})"
`;
exports[`defineProps > custom element retains the props type w/ production mode 1`] = `
"import { defineComponent as _defineComponent } from 'vue'
export default /*#__PURE__*/_defineComponent({
__name: 'app.ce',
props: {
foo: {type: Number}
},
setup(__props: any, { expose: __expose }) {
__expose();
const props = __props
return { props }
}
})"
`;
exports[`defineProps > defineProps w/ runtime options 1`] = ` exports[`defineProps > defineProps w/ runtime options 1`] = `
"import { defineComponent as _defineComponent } from 'vue' "import { defineComponent as _defineComponent } from 'vue'

View File

@ -710,4 +710,35 @@ const props = defineProps({ foo: String })
'da-sh': BindingTypes.PROPS 'da-sh': BindingTypes.PROPS
}) })
}) })
// #8989
test('custom element retains the props type & production mode', () => {
const { content } = compile(
`<script setup lang="ts">
const props = defineProps<{ foo: number}>()
</script>`,
{ isProd: true, customElement: filename => /\.ce\.vue$/.test(filename) },
{ filename: 'app.ce.vue' }
)
expect(content).toMatch(`foo: {type: Number}`)
assertCode(content)
})
test('custom element retains the props type & default value & production mode', () => {
const { content } = compile(
`<script setup lang="ts">
interface Props {
foo?: number;
}
const props = withDefaults(defineProps<Props>(), {
foo: 5.5,
});
</script>`,
{ isProd: true, customElement: filename => /\.ce\.vue$/.test(filename) },
{ filename: 'app.ce.vue' }
)
expect(content).toMatch(`foo: { default: 5.5, type: Number }`)
assertCode(content)
})
}) })

View File

@ -130,6 +130,10 @@ export interface SFCScriptCompileOptions {
* using it, disable this and switch to the [Vue Macros implementation](https://vue-macros.sxzz.moe/features/reactivity-transform.html). * using it, disable this and switch to the [Vue Macros implementation](https://vue-macros.sxzz.moe/features/reactivity-transform.html).
*/ */
reactivityTransform?: boolean reactivityTransform?: boolean
/**
* Transform Vue SFCs into custom elements.
*/
customElement?: boolean | ((filename: string) => boolean)
} }
export interface ImportBinding { export interface ImportBinding {

View File

@ -12,6 +12,7 @@ import { TypeScope } from './resolveType'
export class ScriptCompileContext { export class ScriptCompileContext {
isJS: boolean isJS: boolean
isTS: boolean isTS: boolean
isCE = false
scriptAst: Program | null scriptAst: Program | null
scriptSetupAst: Program | null scriptSetupAst: Program | null
@ -95,6 +96,14 @@ export class ScriptCompileContext {
scriptSetupLang === 'ts' || scriptSetupLang === 'ts' ||
scriptSetupLang === 'tsx' scriptSetupLang === 'tsx'
const customElement = options.customElement
const filename = this.descriptor.filename
if (customElement) {
this.isCE =
typeof customElement === 'boolean'
? customElement
: customElement(filename)
}
// resolve parser plugins // resolve parser plugins
const plugins: ParserPlugin[] = resolveParserPlugins( const plugins: ParserPlugin[] = resolveParserPlugins(
(scriptLang || scriptSetupLang)!, (scriptLang || scriptSetupLang)!,

View File

@ -276,6 +276,17 @@ function genRuntimePropFromType(
defaultString defaultString
])} }` ])} }`
} else { } else {
// #8989 for custom element, should keep the type
if (ctx.isCE) {
if (defaultString) {
return `${finalKey}: ${`{ ${defaultString}, type: ${toRuntimeTypeString(
type
)} }`}`
} else {
return `${finalKey}: {type: ${toRuntimeTypeString(type)}}`
}
}
// production: checks are useless // production: checks are useless
return `${finalKey}: ${defaultString ? `{ ${defaultString} }` : `{}`}` return `${finalKey}: ${defaultString ? `{ ${defaultString} }` : `{}`}`
} }