vuejs / vuejs/core

TransitionGroup - item keys change when using v-if and this messes with the transition

Open
#6,180 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

need discussion scope: transition
Dominant language
TypeScript
Stars
54.4k
Forks
9.2k
Avg merge
1d 5h
Merged PRs (30d)
140

Description

Vue version

3.2.37

Link to minimal reproduction

Reproduction link

Steps to reproduce

I am not 100% sure this is a bug but this code was properly working in Vue2.

Problem is that the keys of items in transition-group get changed when there is a v-if statement. This is a big problem b/c now, when I insert an item into the list, ALL items get animated, not just the inserted one. Here is how to reproduce:

  1. Go to the provided link and open the Console
  2. Click on the "Toggle & Add" button
  3. Check the Console - you will see that with every toggle the item keys are changed
    a. It is also strange why the keys are not exactly as I provided them but are prefixed with "0_item" or "1_item" - maybe this is part of the problem
    b. you can also observe they keys in Vue Devtools
  4. Observe the animation - all items are animated, not only the inserted one

Why I need this: I'm working on a drag-n-drop set of components and my DropList component needs to take care of inserting new items as well as reordering of new items. These 2 cases are managed by a v-if statement in the default slot of transition-group, something like (simplified):

<transition-group ref="transitionGroupRef">
  <template v-if="dropAllowed && dropEntered">
    <template v-if="isReordering">
      <slot v-for="(item, index) of reorderedItems" name="item" :item="item" />
    </template>
    <template v-else>
      <slot v-for="item of itemsBeforePlaceholder" name="item" :item="item" />
      <slot name="placeholder" />
      <slot v-for="item of itemsAfterPlaceholder" name="item" :item="item" />
    </template>
  </template>
  <template v-else>
    <slot v-for="item of items" name="item" :item="item" />
  </template>
</transition-group>
What is expected?

I would expect that the keys of the items do not change just because of the v-if statement as I am providing a list with the same keys

What is actually happening?

Vue is overriding my keys with its own an this messes with the list transition.

System Info

No response

Any additional comments?

No response

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by running the linked minimal reproduction and inspect the TransitionGroup behavior when its slot content switches through v-if. Use the console and Vue Devtools to compare the supplied item keys across toggles. Done means keys remain stable and adding an item animates only the inserted item, including the documented slot structure.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
frontend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.