SoFunction
Updated on 2025-04-03

Vue Learning Notes Advanced Edition Multi-element and Multi-Component Transition

This article introduces the transition of vue multi-element and multi-components. There are a lot of knowledge points in this place and it is very important, so I will add a little note today.

Multi-element transition

For native tags, you can use v-if/v-else.But one thing to note:

When elements with the same label name switch, you need to set a unique value through the key attribute to make Vue differentiate them, otherwise Vue will only replace the content inside the same label for efficiency. Even if technically not necessary, setting keys to multiple elements in the <transition> component is a better practice.

Example:

<transition>
 <button v-if="isEditing" key="save">
  Save
 </button>
 <button v-else key="edit">
  Edit
 </button>
</transition>

In some scenarios, v-if and v-else can also be replaced by setting different states to the key characteristics of the same element. The above example can be rewritten as:

<transition>
 <button v-bind:key="isEditing">
  {{ isEditing ? 'Save' : 'Edit' }}
 </button>
</transition>

Transitions using multiple elements of multiple v-ifs can be rewritten as a single element transition with dynamic attributes bound. For example:

<transition>
 <button v-if="docState === 'saved'" key="saved">
  Edit
 </button>
 <button v-if="docState === 'edited'" key="edited">
  Save
 </button>
 <button v-if="docState === 'editing'" key="editing">
  Cancel
 </button>
</transition>

Can be rewritten as:

<transition>
 <button v-bind:key="docState">
  {{ buttonMessage }}
 </button>
</transition>
computed: {
 buttonMessage: function () {
  switch () {
   case 'saved': return 'Edit'
   case 'edited': return 'Save'
   case 'editing': return 'Cancel'
  }
 }
}

Transition mode

In the transition between elements, there is another problem: both elements are redrawn, and one leaves the transition and the other begins to enter the transition. This is the default behavior of <transition> - entering and leaving happens simultaneously.

One of the most primitive solutions is to run normally when the elements are absolutely positioned above each other.

Another way is to use the transition mode provided by Vue.

  1. in-out:The new element first transitions, and after completion, the current element transitions away.
  2. out-in: The current element first transitions, and after completion, the new element transitions into it.

Rewrite the previous switch button transition with out-in:

<transition name="fade" mode="out-in">
 <!-- ... the buttons ... -->
</transition>

Examples of multi-element transitions

Absolute positioning instances of v-if and v-else

<div class="my-div" >
  <transition name="fade">
    <button class="btn" :key="show" @click="show=!show">{{show ? 'on' : 'off'}}</button>
    <!--<button key="on" v-if="show" class="btn" @click="show = !show">on</button>-->
    <!--<button key="off" v-else class="btn" @click="show = !show">off</button>-->
  </transition>
</div>
    .my-div{
      position: relative;
    }
    .btn{
      position: absolute;
      left: 30px;
      top: 10px;
    }

    .fade-enter-active, .fade-leave-active{
      transition: opacity .5s;
    }
    .fade-enter, .fade-leave-to{
      opacity: 0;
    }

new Vue({
  el:'#app',
  data:{
    show : true
  }
})

Multiple v-if examples

<div class="my-div" >
  <transition name="fade">
    <button class="btn" :key="key" >{{btnContent}}</button>
  </transition>
</div>
    .my-div{
      position: relative;
    }
    .btn{
      position: absolute;
      left: 30px;
      top: 10px;
    }

    .fade-enter-active, .fade-leave-active{
      transition: opacity .5s;
    }
    .fade-enter, .fade-leave-to{
      opacity: 0;
    }

var app = new Vue({
  el:'#app',
  data:{
    key:'add'
  },
  computed:{
    btnContent:function () {
      switch (){
        case 'add' : return 'Add'
        case 'edit' : return 'Edit'
        case 'delete' : return 'Delete'
      }
    }
  }
})

I have not done the right value control here, so if you want to see the transition effect, you can modify the value in the console.

Example of transition mode

<div >
  <transition name="fade" mode="out-in">
    <button :key="show" @click="show=!show">{{show ? 'on' : 'off'}}</button>
  </transition>
</div>
    .fade-enter-active, .fade-leave-active{
      transition: opacity .5s;
    }
    .fade-enter, .fade-leave-to{
      opacity: 0;
    }
new Vue({
  el:'#app',
  data:{
    show : true
  }
})

Multi-component transition

The transition of multiple components is much simpler - we don't need to use the key feature. Instead, we only need to use dynamic components, as an example:

<div >
  <transition name="fade" mode="out-in">
    <component :is="view"></component>
  </transition>
</div>
    .fade-enter-active, .fade-leave-active{
      transition: opacity .5s;
    }
    .fade-enter, .fade-leave-to{
      opacity: 0;
    }
var app = new Vue({
  el:'#app',
  data:{
    view:'v-a'
  },
  components:{
    'v-a':{
      template:'<div> component a </div>'
    },
    'v-b':{
      template:'<div> component b </div>'
    },
  }
})

You can see the transition effect by modifying the values ​​in the console.

The transition animations in the above examples can be defined by yourself, or you can use the custom class hooked functions mentioned in the previous section, etc., so I will not introduce them in detail here.

Thank you for reading, I hope it can help you, and I hope you can support me more.