7

I would like to catch an event and do something when v-if toggles. A conditionally rendered element is rendering. It should be possible to get notified of this, no?

bbsimonbb
  • 27,056
  • 15
  • 80
  • 110

3 Answers3

12

You can setup a watcher on the property that is responsible for the truthy-ness for the conditional rendering (v-if).

html

<div id="app">
    <div v-if="toggleElement">MY ELEMENT</div>
    <button @click="toggleElement = !toggleElement">TOGGLE</button>
</div> 

script

new Vue({
el: '#app',
    data: {
        toggleElement: false
    },
    watch: {
        toggleElement(newValue){
            //do something if toggleElement changes
            alert("Element's v-if toggled");
        }
    }
}) 

Here is the fiddle

tony19
  • 125,647
  • 18
  • 229
  • 307
Vamsi Krishna
  • 30,568
  • 8
  • 70
  • 78
  • 5
    Correct answer. and if the condition in `v-if` is not a simple property but a more complex expression, put that in a computed property instead of the template, and observe the computed property. – Linus Borg Jul 03 '17 at 09:32
3

It would trigger mounted if it would be applied to the component.

So if in your parent you would have:

<template>
<div>
<child v-if='test'/>
</div>
</template>

When test is changed, you would trigger mounted of child.

Marek Urbanowicz
  • 12,659
  • 16
  • 62
  • 87
2

I had this exact topic with a popup that needs to be filled first (via v-if) and then animated with GSAP.

The binding is bonded with the clearance of a function

 <section class="PopupBlok" v-if="$store.state.popup && animateOpen()">

But since the function needs to "give its ok" by returning true, you can't directly animate in the animateOpen() function. To fix this, you postpone your animation for one tick like so:

 animateOpen() {
  this.$nextTick(() => { <Do Animation here> })
  return true

}

Therefore your function gives it's OK, and in the next loop all elements are available for animation.

I assume it would work with setTimeout as well, but $nextTick is the vue-way

holux
  • 21
  • 1