fix(runtime-vapor): v-for move list items are not always effective (#121)

This commit is contained in:
Rizumu Ayaka 2024-02-07 22:01:22 +08:00 committed by GitHub
parent a15f609044
commit ccdc634c24
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 63 additions and 3 deletions

View File

@ -0,0 +1,62 @@
import {
computed,
createFor,
createTextNode,
nextTick,
ref,
renderEffect,
setText,
} from '../src'
import { makeRender } from './_utils'
const define = makeRender()
describe('createFor', () => {
test('basic', async () => {
const list = ref([{ name: '1' }, { name: '2' }, { name: '3' }])
const sort = ref(false)
const sortedList = computed(() =>
sort.value ? Array.from(list.value).reverse() : list.value,
)
const { host } = define(() => {
const n1 = createFor(
() => sortedList.value,
block => {
const n3 = createTextNode()
renderEffect(() => {
const [item] = block.s
setText(n3, item.name)
})
return [n3]
},
)
return [n1]
}).render()
expect(host.innerHTML).toBe('123<!--for-->')
// add
list.value.push({ name: '4' })
await nextTick()
expect(host.innerHTML).toBe('1234<!--for-->')
// move
sort.value = true
await nextTick()
expect(host.innerHTML).toBe('4321<!--for-->')
sort.value = false
await nextTick()
expect(host.innerHTML).toBe('1234<!--for-->')
// change
list.value[0].name = 'a'
await nextTick()
expect(host.innerHTML).toBe('a234<!--for-->')
// remove
list.value = []
await nextTick()
expect(host.innerHTML).toBe('<!--for-->')
})
})

View File

@ -6,7 +6,6 @@ import { type Block, type Fragment, fragmentKey } from './render'
interface ForBlock extends Fragment {
scope: EffectScope
item: any
s: [any, number] // state, use short key since it's used a lot in generated code
update: () => void
key: any
@ -41,7 +40,6 @@ export const createFor = (
nodes: null as any,
update: null as any,
scope,
item,
s: [item, index],
key: getKey && getKey(item, index),
memo: getMemo && getMemo(item),
@ -99,7 +97,7 @@ export const createFor = (
newIndex = oldIndex,
) => {
if (
newItem !== block.item ||
newItem !== block.s[0] ||
newIndex !== oldIndex ||
!isReactive(newItem)
) {