Skip to content

Commit 9af4ea3

Browse files
authored
fix: v-for update on move (#79)
1 parent 167c49d commit 9af4ea3

File tree

1 file changed

+14
-9
lines changed

1 file changed

+14
-9
lines changed

src/directives/for.ts

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -124,38 +124,43 @@ export const _for = (el: Element, exp: string, ctx: Context) => {
124124
blocks = childCtxs.map((s) => mountBlock(s, anchor))
125125
mounted = true
126126
} else {
127-
const nextBlocks: Block[] = []
128127
for (let i = 0; i < blocks.length; i++) {
129128
if (!keyToIndexMap.has(blocks[i].key)) {
130129
blocks[i].remove()
131130
}
132131
}
133-
132+
133+
const nextBlocks: Block[] = []
134134
let i = childCtxs.length
135+
let nextBlock: Block | undefined
136+
let prevMovedBlock: Block | undefined
135137
while (i--) {
136138
const childCtx = childCtxs[i]
137139
const oldIndex = prevKeyToIndexMap.get(childCtx.key)
138-
const next = childCtxs[i + 1]
139-
const nextBlockOldIndex = next && prevKeyToIndexMap.get(next.key)
140-
const nextBlock =
141-
nextBlockOldIndex == null ? undefined : blocks[nextBlockOldIndex]
140+
let block
142141
if (oldIndex == null) {
143142
// new
144-
nextBlocks[i] = mountBlock(
143+
block = mountBlock(
145144
childCtx,
146145
nextBlock ? nextBlock.el : anchor
147146
)
148147
} else {
149148
// update
150-
const block = (nextBlocks[i] = blocks[oldIndex])
149+
block = blocks[oldIndex]
151150
Object.assign(block.ctx.scope, childCtx.scope)
152151
if (oldIndex !== i) {
153152
// moved
154-
if (blocks[oldIndex + 1] !== nextBlock) {
153+
if (
154+
blocks[oldIndex + 1] !== nextBlock ||
155+
// If the next has moved, it must move too
156+
prevMovedBlock === nextBlock
157+
) {
158+
prevMovedBlock = block
155159
block.insert(parent, nextBlock ? nextBlock.el : anchor)
156160
}
157161
}
158162
}
163+
nextBlocks.unshift(nextBlock = block)
159164
}
160165
blocks = nextBlocks
161166
}

0 commit comments

Comments
 (0)