Tom
Tom

Reputation: 688

Can't stop Vue JS (v2) from reusing components

I have a Vue app that conditionally displays sets of the same component, I'd like to tie in to the created or mounted methods, but Vue keeps re-using earlier components and not triggering the methods. I've tried wrapping the components in keep-alive tags to no effect.

The code below shows what you would expect on the page: changing someVariable to 'test1' or 'test2' shows the relevant components, but the created/mounted methods only fire a maximum of 2 times (e.g. changing someVariable to 'test1' logs creation and mounting of 1 component with the label type1, then changing it to 'test2' only logs 1 more component with the label type3).

Currently using v2.1.10

HTML

<div id="app">
    <div v-if="someVariable === 'test1'">
        <keep-alive>
            <test-component data-type="type1"></test-component>
        </keep-alive>
    </div>

    <div v-if="someVariable === 'test2'">
        <keep-alive>
            <test-component data-type="type2"></test-component>
        </keep-alive>

        <keep-alive>
            <test-component data-type="type3"></test-component>
        </keep-alive>
    </div>
</div>

JS/Vue

Vue.component('test-component', {
    props: ['data-type'],
    template: '<div><p>In the component: {{ dataType }}</p></div>',
    created: function () {
        console.log('component created: ', this.dataType);
    },
    mounted: function () {
        console.log('component mounted: ', this.dataType);
    }
});

var app = new Vue({
    el: '#app',
    data: {
        someVariable: ""
    }
});

Upvotes: 3

Views: 2811

Answers (2)

Cristi Jora
Cristi Jora

Reputation: 1752

For your specific example removing keep-alive from the second if should do the trick https://jsfiddle.net/z11fe07p/464/

An interesting thing is that vue seems to re-use the previously rendered component. So if you have one component in the first if when switching to the next if with 2 components it will re-use one component and create a new one for the second component from the block. When getting back to the first if block it will re-use one of the 2 already rendered components.

As mentioned above, a watcher is more suited for such cases, thus getting you rid of handling logic in places where you don't have full control. You can see this tip right here in the docs https://v2.vuejs.org/v2/api/#updated

Upvotes: 2

Clorichel
Clorichel

Reputation: 2080

You should use a watcher on your someVariable instead of trying to hook on created and mounted hooks.

Components are created, and mounted the first time they are visible (rendered). There are NO "shown" or "hidden" hooks.

See https://v2.vuejs.org/v2/guide/computed.html#Watchers:

watch: {
  someVariable: function (newValue) {
    // test newValue and do what you have to do!
  }
}

Upvotes: 3

Related Questions