why component is not destroyed under v-if

Viewed 9553

I have very simple example. There are two divs each with v-if with same variable, one with true and one with false. There is component nested inside the each of the divs (same component).

What I see (from the console.log) is that even there is v-if, the component is not destroyed and created but rather reused.

Is this bug? feature? Because I was relying on them to be destroyed (the problem occur in some more complex component).

Thanks.

Html and javascript below, there is also jsfiddle https://jsfiddle.net/ekeydar/p64ewLd1/3/

This is the html:

<div id="app">
  <button @click="show1=!show1">
    Toggle  
  </button>
  <div v-if="show1">
    <my-comp title="comp1"/>
  </div>
  <div v-if="!show1">
    <my-comp title="comp2"/>
  </div>
</div>

This is the javascript:

Vue.component('my-comp', {
    props: ['title'],
  template: '<h1>{{title}}</h1>',
  created: function() {
    console.log('my-comp.created title='+ this.title);
  },
  destroyed: function()  {
    console.log('my-comp.destroyed title='+ this.title);
  }
}),

new Vue({
  el: '#app',
  data: {
    show1: true,
  },
})
3 Answers

This is the intended functionality for Vue. In order to let Vue know that the component shouldn't be reused but instead destroyed and create a different component, add a key attribute to the components.

Example:

<div v-if="show1">
    <my-comp title="comp1" key="somekeyhere"/>
</div>
<div v-else>
    <my-comp title="comp2" key="someotherkeyhere"/>
</div>

Note that you could also put the key attribute to the div, but I think it's cleaner to add it on the component since the div itself can be reused without issues.

Here's a little trick (or horrible hack if you like) if you want your component to always be destroyed when it is hidden (e.g. to save memory). Use NaN as the key. Since NaN is never equal to itself Vue will always think it is a different element.

  <div v-if="show1">
    <my-comp title="comp1" :key="NaN"/>
  </div>
  <div v-if="!show1">
    <my-comp title="comp2" :key="NaN"/>
  </div>

You need :key= rather than key= because otherwise the attribute will be a string with the value "NaN".

The difference between v-if and v-show is just whether or not the element exists in the DOM, not whether or not it is created. v-if removes it from the DOM when false, v-show just hides it. The component however is not destroyed either way.

Related