From: edison Date: Mon, 19 Jan 2026 00:43:16 +0000 (+0800) Subject: fix(compile-sfc): correctly handle variable shadowing in for loop for `defineProps... X-Git-Tag: v3.5.27~8 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6a1bb50594db03904f401fc33ea85afa8fa71cf7;p=thirdparty%2Fvuejs%2Fcore.git fix(compile-sfc): correctly handle variable shadowing in for loop for `defineProps` destructuring. (#14296) close #14294 --- diff --git a/packages/compiler-sfc/__tests__/compileScript/__snapshots__/definePropsDestructure.spec.ts.snap b/packages/compiler-sfc/__tests__/compileScript/__snapshots__/definePropsDestructure.spec.ts.snap index 9306d31da9..d3d6a31c2f 100644 --- a/packages/compiler-sfc/__tests__/compileScript/__snapshots__/definePropsDestructure.spec.ts.snap +++ b/packages/compiler-sfc/__tests__/compileScript/__snapshots__/definePropsDestructure.spec.ts.snap @@ -192,6 +192,32 @@ return () => {} }" `; +exports[`sfc reactive props destructure > for-of loop variable shadowing 1`] = ` +"import { defineComponent as _defineComponent } from 'vue' +interface Props { + msg: string; + input: string[]; + } + +export default /*@__PURE__*/_defineComponent({ + props: { + msg: { type: String, required: true }, + input: { type: Array, required: true } + }, + setup(__props: any) { + + + for (const msg of __props.input) { + console.log('MESSAGE', msg); + } + console.log('NOT FAIL', { msg: __props.msg }); + +return () => {} +} + +})" +`; + exports[`sfc reactive props destructure > handle function parameters with same name as destructured props 1`] = ` " export default { @@ -309,6 +335,28 @@ return (_ctx, _cache) => { }" `; +exports[`sfc reactive props destructure > regular for loop variable shadowing 1`] = ` +"import { defineComponent as _defineComponent } from 'vue' + +export default /*@__PURE__*/_defineComponent({ + props: { + i: { type: Number, required: true }, + len: { type: Number, required: true } + }, + setup(__props: any) { + + + for (let i = 0; i < __props.len; i++) { + console.log('INDEX', i); + } + console.log('AFTER', { i: __props.i }); + +return () => {} +} + +})" +`; + exports[`sfc reactive props destructure > rest spread 1`] = ` "import { createPropsRestProxy as _createPropsRestProxy } from 'vue' diff --git a/packages/compiler-sfc/__tests__/compileScript/definePropsDestructure.spec.ts b/packages/compiler-sfc/__tests__/compileScript/definePropsDestructure.spec.ts index 25dd817bbe..cfb73a2ab2 100644 --- a/packages/compiler-sfc/__tests__/compileScript/definePropsDestructure.spec.ts +++ b/packages/compiler-sfc/__tests__/compileScript/definePropsDestructure.spec.ts @@ -68,6 +68,46 @@ describe('sfc reactive props destructure', () => { }) }) + test('for-of loop variable shadowing', () => { + const { content } = compile(` + + `) + // inside loop: should use local variable + expect(content).toMatch(`for (const msg of __props.input)`) + expect(content).toMatch(`console.log('MESSAGE', msg)`) + // after loop: should restore to prop reference + expect(content).toMatch(`console.log('NOT FAIL', { msg: __props.msg })`) + assertCode(content) + }) + + test('regular for loop variable shadowing', () => { + const { content } = compile(` + + `) + // inside loop: should use local variable + expect(content).toMatch(`for (let i = 0; i < __props.len; i++)`) + expect(content).toMatch(`console.log('INDEX', i)`) + // after loop: should restore to prop reference + expect(content).toMatch(`console.log('AFTER', { i: __props.i })`) + assertCode(content) + }) + test('default values w/ array runtime declaration', () => { const { content } = compile(`