Skip to content

Commit 81b3d36

Browse files
committed
fix(vapor): destructure in v-for
1 parent 0c7817c commit 81b3d36

File tree

5 files changed

+48
-18
lines changed

5 files changed

+48
-18
lines changed

packages/compiler-vapor/__tests__/transforms/__snapshots__/vFor.spec.ts.snap

+3-3
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ const t0 = _template("<div></div>")
77
export function render(_ctx) {
88
const n0 = _createFor(() => (_ctx.list), _withDestructure(([[id, ...other], index]) => [id, other, index], (_ctx0) => {
99
const n2 = t0()
10-
_renderEffect(() => _setText(n2, _ctx0[0].value + _ctx0[1].value + _ctx0[2].value))
10+
_renderEffect(() => _setText(n2, _ctx0[0] + _ctx0[1] + _ctx0[2]))
1111
return n2
1212
}), ([id, ...other], index) => (id))
1313
return n0
@@ -87,7 +87,7 @@ const t0 = _template("<div></div>")
8787
export function render(_ctx) {
8888
const n0 = _createFor(() => (_ctx.list), _withDestructure(([{ id, ...other }, index]) => [id, other, index], (_ctx0) => {
8989
const n2 = t0()
90-
_renderEffect(() => _setText(n2, _ctx0[0].value + _ctx0[1].value + _ctx0[2].value))
90+
_renderEffect(() => _setText(n2, _ctx0[0] + _ctx0[1] + _ctx0[2]))
9191
return n2
9292
}), ({ id, ...other }, index) => (id))
9393
return n0
@@ -101,7 +101,7 @@ const t0 = _template("<div></div>")
101101
export function render(_ctx) {
102102
const n0 = _createFor(() => (_ctx.list), _withDestructure(([{ foo = bar, baz: [qux = quux] }]) => [foo, qux], (_ctx0) => {
103103
const n2 = t0()
104-
_renderEffect(() => _setText(n2, _ctx0[0].value + _ctx.bar + _ctx.baz + _ctx0[1].value + _ctx.quux))
104+
_renderEffect(() => _setText(n2, _ctx0[0] + _ctx.bar + _ctx.baz + _ctx0[1] + _ctx.quux))
105105
return n2
106106
}))
107107
return n0

packages/compiler-vapor/__tests__/transforms/vFor.spec.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ describe('compiler: v-for', () => {
130130
)
131131
expect(code).matchSnapshot()
132132
expect(code).contains(`([{ id, ...other }, index]) => [id, other, index]`)
133-
expect(code).contains(`_ctx0[0].value + _ctx0[1].value + _ctx0[2].value`)
133+
expect(code).contains(`_ctx0[0] + _ctx0[1] + _ctx0[2]`)
134134
expect(ir.block.operation[0]).toMatchObject({
135135
type: IRNodeTypes.FOR,
136136
source: {
@@ -163,7 +163,7 @@ describe('compiler: v-for', () => {
163163
)
164164
expect(code).matchSnapshot()
165165
expect(code).contains(`([[id, ...other], index]) => [id, other, index]`)
166-
expect(code).contains(`_ctx0[0].value + _ctx0[1].value + _ctx0[2]`)
166+
expect(code).contains(`_ctx0[0] + _ctx0[1] + _ctx0[2]`)
167167
expect(ir.block.operation[0]).toMatchObject({
168168
type: IRNodeTypes.FOR,
169169
source: {
@@ -199,7 +199,7 @@ describe('compiler: v-for', () => {
199199
expect(code).matchSnapshot()
200200
expect(code).contains(`([{ foo = bar, baz: [qux = quux] }]) => [foo, qux]`)
201201
expect(code).contains(
202-
`_ctx0[0].value + _ctx.bar + _ctx.baz + _ctx0[1].value + _ctx.quux`,
202+
`_ctx0[0] + _ctx.bar + _ctx.baz + _ctx0[1] + _ctx.quux`,
203203
)
204204
expect(ir.block.operation[0]).toMatchObject({
205205
type: IRNodeTypes.FOR,

packages/compiler-vapor/src/generators/for.ts

+7-6
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ export function genFor(
2929
container,
3030
} = oper
3131

32-
let isDestructureAssignment = false
32+
let isDestructure = false
3333
let rawValue: string | null = null
3434
const rawKey = key && key.content
3535
const rawIndex = index && index.content
@@ -39,7 +39,7 @@ export function genFor(
3939
let blockFn = genBlockFn()
4040
const simpleIdMap: Record<string, null> = genSimpleIdMap()
4141

42-
if (isDestructureAssignment) {
42+
if (isDestructure) {
4343
const idMap: Record<string, null> = {}
4444
idsInValue.forEach(id => (idMap[id] = null))
4545
if (rawKey) idMap[rawKey] = null
@@ -82,7 +82,7 @@ export function genFor(
8282
const idsInValue = new Set<string>()
8383
if (value) {
8484
rawValue = value && value.content
85-
if ((isDestructureAssignment = !!value.ast)) {
85+
if ((isDestructure = !!value.ast)) {
8686
walkIdentifiers(
8787
value.ast,
8888
(id, _, __, ___, isLocal) => {
@@ -103,12 +103,13 @@ export function genFor(
103103
const idMap: Record<string, string | null> = {}
104104
if (context.options.prefixIdentifiers) {
105105
propsName = `_ctx${depth}`
106+
let suffix = isDestructure ? '' : '.value'
106107
Array.from(idsInValue).forEach(
107-
(id, idIndex) => (idMap[id] = `${propsName}[${idIndex}].value`),
108+
(id, idIndex) => (idMap[id] = `${propsName}[${idIndex}]${suffix}`),
108109
)
109-
if (rawKey) idMap[rawKey] = `${propsName}[${idsInValue.size}].value`
110+
if (rawKey) idMap[rawKey] = `${propsName}[${idsInValue.size}]${suffix}`
110111
if (rawIndex)
111-
idMap[rawIndex] = `${propsName}[${idsInValue.size + 1}].value`
112+
idMap[rawIndex] = `${propsName}[${idsInValue.size + 1}]${suffix}`
112113
} else {
113114
propsName = `[${[rawValue || ((rawKey || rawIndex) && '_'), rawKey || (rawIndex && '__'), rawIndex].filter(Boolean).join(', ')}]`
114115
}

packages/runtime-vapor/__tests__/for.spec.ts

+25
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ import {
44
ref,
55
renderEffect,
66
shallowRef,
7+
template,
78
triggerRef,
9+
withDestructure,
810
} from '../src'
911
import { makeRender } from './_utils'
1012

@@ -579,4 +581,27 @@ describe('createFor', () => {
579581
await nextTick()
580582
expectCalledTimesToBe('Clear rows', 1, 0, 0, 0)
581583
})
584+
585+
test('withDestructure', () => {
586+
const list = ref([{ name: 'a' }, { name: 'b' }, { name: 'c' }])
587+
588+
const { host } = define(() => {
589+
const n1 = createFor(
590+
() => list.value,
591+
withDestructure(
592+
([{ name }, index]) => [name, index],
593+
ctx => {
594+
const span = template(`<li>${ctx[1]}. ${ctx[0]}</li>`)()
595+
return span
596+
},
597+
),
598+
item => item.name,
599+
)
600+
return n1
601+
}).render()
602+
603+
expect(host.innerHTML).toBe(
604+
'<li>0. a</li><li>1. b</li><li>2. c</li><!--for-->',
605+
)
606+
})
582607
})

packages/runtime-vapor/src/destructure.ts

+10-6
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,18 @@
1-
import { shallowReactive } from '@vue/reactivity'
1+
import {
2+
type ShallowUnwrapRef,
3+
proxyRefs,
4+
shallowReactive,
5+
} from '@vue/reactivity'
26
import { renderEffect } from './renderEffect'
37

4-
export function withDestructure<P extends any[], R>(
5-
assign: (...args: P) => any[],
8+
export function withDestructure<T extends any[], R>(
9+
assign: (data: ShallowUnwrapRef<T>) => any[],
610
block: (ctx: any[]) => R,
7-
): (...args: P) => R {
8-
return (...args: P) => {
11+
): (data: T) => R {
12+
return (data: T) => {
913
const ctx = shallowReactive<any[]>([])
1014
renderEffect(() => {
11-
const res = assign(...args)
15+
const res = assign(proxyRefs(data))
1216
const len = res.length
1317
for (let i = 0; i < len; i++) {
1418
ctx[i] = res[i]

0 commit comments

Comments
 (0)