Browse Source

fix(compiler-sfc): properly analyze destructured bindings with dynamic keys

fix #4540
Evan You 4 năm trước cách đây
mục cha
commit
a6e5f82d8e

+ 13 - 0
packages/compiler-sfc/__tests__/__snapshots__/compileScript.spec.ts.snap

@@ -96,6 +96,19 @@ export default /*#__PURE__*/ Object.assign(__default__, {
 })"
 `;
 
+exports[`SFC compile <script setup> binding analysis for destructur 1`] = `
+"export default {
+  setup(__props, { expose }) {
+  expose()
+
+      const { foo, b: bar, ['x' + 'y']: baz, x: { y, zz: { z }}} = {}
+      
+return { foo, bar, baz, y, z }
+}
+
+}"
+`;
+
 exports[`SFC compile <script setup> defineEmits() 1`] = `
 "export default {
   emits: ['foo', 'bar'],

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

@@ -36,6 +36,23 @@ describe('SFC compile <script setup>', () => {
     assertCode(content)
   })
 
+  test('binding analysis for destructur', () => {
+    const { content, bindings } = compile(`
+      <script setup>
+      const { foo, b: bar, ['x' + 'y']: baz, x: { y, zz: { z }}} = {}
+      </script>
+      `)
+    expect(content).toMatch('return { foo, bar, baz, y, z }')
+    expect(bindings).toStrictEqual({
+      foo: BindingTypes.SETUP_MAYBE_REF,
+      bar: BindingTypes.SETUP_MAYBE_REF,
+      baz: BindingTypes.SETUP_MAYBE_REF,
+      y: BindingTypes.SETUP_MAYBE_REF,
+      z: BindingTypes.SETUP_MAYBE_REF
+    })
+    assertCode(content)
+  })
+
   test('defineProps()', () => {
     const { content, bindings } = compile(`
 <script setup>

+ 10 - 13
packages/compiler-sfc/src/compileScript.ts

@@ -1347,19 +1347,16 @@ function walkObjectPattern(
 ) {
   for (const p of node.properties) {
     if (p.type === 'ObjectProperty') {
-      // key can only be Identifier in ObjectPattern
-      if (p.key.type === 'Identifier') {
-        if (p.key === p.value) {
-          // const { x } = ...
-          const type = isDefineCall
-            ? BindingTypes.SETUP_CONST
-            : isConst
-            ? BindingTypes.SETUP_MAYBE_REF
-            : BindingTypes.SETUP_LET
-          registerBinding(bindings, p.key, type)
-        } else {
-          walkPattern(p.value, bindings, isConst, isDefineCall)
-        }
+      if (p.key.type === 'Identifier' && p.key === p.value) {
+        // shorthand: const { x } = ...
+        const type = isDefineCall
+          ? BindingTypes.SETUP_CONST
+          : isConst
+          ? BindingTypes.SETUP_MAYBE_REF
+          : BindingTypes.SETUP_LET
+        registerBinding(bindings, p.key, type)
+      } else {
+        walkPattern(p.value, bindings, isConst, isDefineCall)
       }
     } else {
       // ...rest