feat(compiler-sfc): enable reactive props destructure by default

Also allow prohibiting usage via config.
RFC: https://github.com/vuejs/rfcs/discussions/502
This commit is contained in:
Evan You 2024-04-29 10:45:48 +08:00
parent 75c8cf63a1
commit d2dac0e359
No known key found for this signature in database
GPG Key ID: B9D421896CA450FB
4 changed files with 26 additions and 14 deletions

View File

@ -597,11 +597,29 @@ const props = defineProps({ foo: String })
foo: Foo
}>()
</script>`,
{
propsDestructure: false,
},
)
expect(content).toMatch(`const { foo } = __props`)
assertCode(content)
})
test('prohibiting reactive destructure', () => {
expect(() =>
compile(
`<script setup lang="ts">
const { foo } = defineProps<{
foo: Foo
}>()
</script>`,
{
propsDestructure: 'error',
},
),
).toThrow()
})
describe('errors', () => {
test('w/ both type and non-type args', () => {
expect(() => {

View File

@ -6,7 +6,6 @@ describe('sfc reactive props destructure', () => {
function compile(src: string, options?: Partial<SFCScriptCompileOptions>) {
return compileSFCScript(src, {
inlineTemplate: true,
propsDestructure: true,
...options,
})
}

View File

@ -106,10 +106,11 @@ export interface SFCScriptCompileOptions {
*/
hoistStatic?: boolean
/**
* (**Experimental**) Enable reactive destructure for `defineProps`
* @default false
* Set to `false` to disable reactive destructure for `defineProps` (pre-3.5
* behavior), or set to `'error'` to throw hard error on props destructures.
* @default true
*/
propsDestructure?: boolean
propsDestructure?: boolean | 'error'
/**
* File system access methods to be used when resolving types
* imported in SFC macros. Defaults to ts.sys in Node.js, can be overwritten

View File

@ -22,23 +22,17 @@ import { genPropsAccessExp } from '@vue/shared'
import { isCallOf, resolveObjectKey } from './utils'
import type { ScriptCompileContext } from './context'
import { DEFINE_PROPS } from './defineProps'
import { warnOnce } from '../warn'
export function processPropsDestructure(
ctx: ScriptCompileContext,
declId: ObjectPattern,
) {
if (!ctx.options.propsDestructure) {
if (ctx.options.propsDestructure === 'error') {
ctx.error(`Props destructure is explicitly prohibited via config.`, declId)
} else if (ctx.options.propsDestructure === false) {
return
}
warnOnce(
`This project is using reactive props destructure, which is an experimental ` +
`feature. It may receive breaking changes or be removed in the future, so ` +
`use at your own risk.\n` +
`To stay updated, follow the RFC at https://github.com/vuejs/rfcs/discussions/502.`,
)
ctx.propsDestructureDecl = declId
const registerBinding = (
@ -104,7 +98,7 @@ export function transformDestructuredProps(
ctx: ScriptCompileContext,
vueImportAliases: Record<string, string>,
) {
if (!ctx.options.propsDestructure) {
if (ctx.options.propsDestructure === false) {
return
}