浏览代码

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

Also allow prohibiting usage via config.
RFC: https://github.com/vuejs/rfcs/discussions/502
Evan You 2 年之前
父节点
当前提交
d2dac0e359

+ 18 - 0
packages/compiler-sfc/__tests__/compileScript/defineProps.spec.ts

@@ -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(() => {

+ 0 - 1
packages/compiler-sfc/__tests__/compileScript/definePropsDestructure.spec.ts

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

+ 4 - 3
packages/compiler-sfc/src/compileScript.ts

@@ -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

+ 4 - 10
packages/compiler-sfc/src/script/definePropsDestructure.ts

@@ -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
   }