2

I'm building a Vue.js based SPA where I want to transition between several parts of the content:

<template>
    <transition name="fade">
        <component 
            :is="options[active].type" 
            v-bind="options[active].props"
        />
    </transition>
</template>

<script>
const content = [
    {type: 'ContentHeader', props: {...}},
    {type: 'ContentModule', props: {...}},
    {type: 'ContentModule', props: {...}}
];

import ContentHeader from '...';
import ContentModule from '...';

export default {
    components: {
        ContentHeader,
        ContentModule
    },

    data: () => ({
        active: 0,
        options: content
    })
};
</script>

When I change the active property from 0 to 1, the dynamic component changes and the transition is triggered. Switching to the last component doesn't, though - it has the same element type as the one before. The component's props are different and are rendered correctly but the transition doesn't realize a change has happened and won't fire.

Any ideas how I could solve that - or for a different approach to combine modules in a transition?

Dan
  • 59,490
  • 13
  • 101
  • 110
wortwart
  • 3,139
  • 27
  • 31

1 Answers1

3

Since the component is reused, there is no fresh instance to swap in and the transition isn't triggered, because the instance/template is reused. That is the default behavior. But you can change that by using a unique key:

<component 
    :is="options[active].type" 
    v-bind="options[active].props"
    :key="active"
/>

Here I'm using the active index as a unique identifier to tell Vue to use a fresh instance for each component.

This question often comes up in the context of a router having multiple routes using the same component, and the answer then is to use a key as well.

Dan
  • 59,490
  • 13
  • 101
  • 110