From: 三咲智子 Kevin Deng Date: Fri, 15 Nov 2024 22:33:38 +0000 (+0800) Subject: fix(vapor): destructure in `v-for` X-Git-Tag: v3.6.0-alpha.1~16^2~270 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=81b3d36304e63df0d6657f3546763e958503f4af;p=thirdparty%2Fvuejs%2Fcore.git fix(vapor): destructure in `v-for` --- diff --git a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vFor.spec.ts.snap b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vFor.spec.ts.snap index 55354aec57..b77a3f7cdb 100644 --- a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vFor.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vFor.spec.ts.snap @@ -7,7 +7,7 @@ const t0 = _template("
") export function render(_ctx) { const n0 = _createFor(() => (_ctx.list), _withDestructure(([[id, ...other], index]) => [id, other, index], (_ctx0) => { const n2 = t0() - _renderEffect(() => _setText(n2, _ctx0[0].value + _ctx0[1].value + _ctx0[2].value)) + _renderEffect(() => _setText(n2, _ctx0[0] + _ctx0[1] + _ctx0[2])) return n2 }), ([id, ...other], index) => (id)) return n0 @@ -87,7 +87,7 @@ const t0 = _template("
") export function render(_ctx) { const n0 = _createFor(() => (_ctx.list), _withDestructure(([{ id, ...other }, index]) => [id, other, index], (_ctx0) => { const n2 = t0() - _renderEffect(() => _setText(n2, _ctx0[0].value + _ctx0[1].value + _ctx0[2].value)) + _renderEffect(() => _setText(n2, _ctx0[0] + _ctx0[1] + _ctx0[2])) return n2 }), ({ id, ...other }, index) => (id)) return n0 @@ -101,7 +101,7 @@ const t0 = _template("
") export function render(_ctx) { const n0 = _createFor(() => (_ctx.list), _withDestructure(([{ foo = bar, baz: [qux = quux] }]) => [foo, qux], (_ctx0) => { const n2 = t0() - _renderEffect(() => _setText(n2, _ctx0[0].value + _ctx.bar + _ctx.baz + _ctx0[1].value + _ctx.quux)) + _renderEffect(() => _setText(n2, _ctx0[0] + _ctx.bar + _ctx.baz + _ctx0[1] + _ctx.quux)) return n2 })) return n0 diff --git a/packages/compiler-vapor/__tests__/transforms/vFor.spec.ts b/packages/compiler-vapor/__tests__/transforms/vFor.spec.ts index 58064e4c3d..45b33c7a4d 100644 --- a/packages/compiler-vapor/__tests__/transforms/vFor.spec.ts +++ b/packages/compiler-vapor/__tests__/transforms/vFor.spec.ts @@ -130,7 +130,7 @@ describe('compiler: v-for', () => { ) expect(code).matchSnapshot() expect(code).contains(`([{ id, ...other }, index]) => [id, other, index]`) - expect(code).contains(`_ctx0[0].value + _ctx0[1].value + _ctx0[2].value`) + expect(code).contains(`_ctx0[0] + _ctx0[1] + _ctx0[2]`) expect(ir.block.operation[0]).toMatchObject({ type: IRNodeTypes.FOR, source: { @@ -163,7 +163,7 @@ describe('compiler: v-for', () => { ) expect(code).matchSnapshot() expect(code).contains(`([[id, ...other], index]) => [id, other, index]`) - expect(code).contains(`_ctx0[0].value + _ctx0[1].value + _ctx0[2]`) + expect(code).contains(`_ctx0[0] + _ctx0[1] + _ctx0[2]`) expect(ir.block.operation[0]).toMatchObject({ type: IRNodeTypes.FOR, source: { @@ -199,7 +199,7 @@ describe('compiler: v-for', () => { expect(code).matchSnapshot() expect(code).contains(`([{ foo = bar, baz: [qux = quux] }]) => [foo, qux]`) expect(code).contains( - `_ctx0[0].value + _ctx.bar + _ctx.baz + _ctx0[1].value + _ctx.quux`, + `_ctx0[0] + _ctx.bar + _ctx.baz + _ctx0[1] + _ctx.quux`, ) expect(ir.block.operation[0]).toMatchObject({ type: IRNodeTypes.FOR, diff --git a/packages/compiler-vapor/src/generators/for.ts b/packages/compiler-vapor/src/generators/for.ts index ddfd61e1b6..8a90901d45 100644 --- a/packages/compiler-vapor/src/generators/for.ts +++ b/packages/compiler-vapor/src/generators/for.ts @@ -29,7 +29,7 @@ export function genFor( container, } = oper - let isDestructureAssignment = false + let isDestructure = false let rawValue: string | null = null const rawKey = key && key.content const rawIndex = index && index.content @@ -39,7 +39,7 @@ export function genFor( let blockFn = genBlockFn() const simpleIdMap: Record = genSimpleIdMap() - if (isDestructureAssignment) { + if (isDestructure) { const idMap: Record = {} idsInValue.forEach(id => (idMap[id] = null)) if (rawKey) idMap[rawKey] = null @@ -82,7 +82,7 @@ export function genFor( const idsInValue = new Set() if (value) { rawValue = value && value.content - if ((isDestructureAssignment = !!value.ast)) { + if ((isDestructure = !!value.ast)) { walkIdentifiers( value.ast, (id, _, __, ___, isLocal) => { @@ -103,12 +103,13 @@ export function genFor( const idMap: Record = {} if (context.options.prefixIdentifiers) { propsName = `_ctx${depth}` + let suffix = isDestructure ? '' : '.value' Array.from(idsInValue).forEach( - (id, idIndex) => (idMap[id] = `${propsName}[${idIndex}].value`), + (id, idIndex) => (idMap[id] = `${propsName}[${idIndex}]${suffix}`), ) - if (rawKey) idMap[rawKey] = `${propsName}[${idsInValue.size}].value` + if (rawKey) idMap[rawKey] = `${propsName}[${idsInValue.size}]${suffix}` if (rawIndex) - idMap[rawIndex] = `${propsName}[${idsInValue.size + 1}].value` + idMap[rawIndex] = `${propsName}[${idsInValue.size + 1}]${suffix}` } else { propsName = `[${[rawValue || ((rawKey || rawIndex) && '_'), rawKey || (rawIndex && '__'), rawIndex].filter(Boolean).join(', ')}]` } diff --git a/packages/runtime-vapor/__tests__/for.spec.ts b/packages/runtime-vapor/__tests__/for.spec.ts index 5854298ace..0ee09a9ad1 100644 --- a/packages/runtime-vapor/__tests__/for.spec.ts +++ b/packages/runtime-vapor/__tests__/for.spec.ts @@ -4,7 +4,9 @@ import { ref, renderEffect, shallowRef, + template, triggerRef, + withDestructure, } from '../src' import { makeRender } from './_utils' @@ -579,4 +581,27 @@ describe('createFor', () => { await nextTick() expectCalledTimesToBe('Clear rows', 1, 0, 0, 0) }) + + test('withDestructure', () => { + const list = ref([{ name: 'a' }, { name: 'b' }, { name: 'c' }]) + + const { host } = define(() => { + const n1 = createFor( + () => list.value, + withDestructure( + ([{ name }, index]) => [name, index], + ctx => { + const span = template(`
  • ${ctx[1]}. ${ctx[0]}
  • `)() + return span + }, + ), + item => item.name, + ) + return n1 + }).render() + + expect(host.innerHTML).toBe( + '
  • 0. a
  • 1. b
  • 2. c
  • ', + ) + }) }) diff --git a/packages/runtime-vapor/src/destructure.ts b/packages/runtime-vapor/src/destructure.ts index 20030dd328..8e68f453fa 100644 --- a/packages/runtime-vapor/src/destructure.ts +++ b/packages/runtime-vapor/src/destructure.ts @@ -1,14 +1,18 @@ -import { shallowReactive } from '@vue/reactivity' +import { + type ShallowUnwrapRef, + proxyRefs, + shallowReactive, +} from '@vue/reactivity' import { renderEffect } from './renderEffect' -export function withDestructure

    ( - assign: (...args: P) => any[], +export function withDestructure( + assign: (data: ShallowUnwrapRef) => any[], block: (ctx: any[]) => R, -): (...args: P) => R { - return (...args: P) => { +): (data: T) => R { + return (data: T) => { const ctx = shallowReactive([]) renderEffect(() => { - const res = assign(...args) + const res = assign(proxyRefs(data)) const len = res.length for (let i = 0; i < len; i++) { ctx[i] = res[i]