mirror of https://github.com/vuejs/core.git
fix(runtime-vapor): v-for move list items are not always effective (#121)
This commit is contained in:
parent
a15f609044
commit
ccdc634c24
|
@ -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-->')
|
||||||
|
})
|
||||||
|
})
|
|
@ -6,7 +6,6 @@ import { type Block, type Fragment, fragmentKey } from './render'
|
||||||
|
|
||||||
interface ForBlock extends Fragment {
|
interface ForBlock extends Fragment {
|
||||||
scope: EffectScope
|
scope: EffectScope
|
||||||
item: any
|
|
||||||
s: [any, number] // state, use short key since it's used a lot in generated code
|
s: [any, number] // state, use short key since it's used a lot in generated code
|
||||||
update: () => void
|
update: () => void
|
||||||
key: any
|
key: any
|
||||||
|
@ -41,7 +40,6 @@ export const createFor = (
|
||||||
nodes: null as any,
|
nodes: null as any,
|
||||||
update: null as any,
|
update: null as any,
|
||||||
scope,
|
scope,
|
||||||
item,
|
|
||||||
s: [item, index],
|
s: [item, index],
|
||||||
key: getKey && getKey(item, index),
|
key: getKey && getKey(item, index),
|
||||||
memo: getMemo && getMemo(item),
|
memo: getMemo && getMemo(item),
|
||||||
|
@ -99,7 +97,7 @@ export const createFor = (
|
||||||
newIndex = oldIndex,
|
newIndex = oldIndex,
|
||||||
) => {
|
) => {
|
||||||
if (
|
if (
|
||||||
newItem !== block.item ||
|
newItem !== block.s[0] ||
|
||||||
newIndex !== oldIndex ||
|
newIndex !== oldIndex ||
|
||||||
!isReactive(newItem)
|
!isReactive(newItem)
|
||||||
) {
|
) {
|
||||||
|
|
Loading…
Reference in New Issue