Reputation: 14393
In a vue js app, how to trigger a transition event on an element inside a component, when this component leaves?
The element has a v-if="showElement"
, then showElement
is set to false when the component transition fires on leave
… but showElement
is not changing in the view.
Here is a codepen: https://codepen.io/francoisromain-1472161924/pen/RGPYOb?editors=1111
and the code:
html:
<div id="app">
<a @click="show = !show">Show {{ show }}</a>
<page-component v-if="show"></page-component>
</div>
<script id="pageComponent" type="x-template">
<div class="component" transition="component">
<p>Component</p>
<div v-if="showElement" class="element" transition="element">
<p>Element</b>
</div>
</div>
</script>
js:
var pageComponent = Vue.extend({
template: '#pageComponent',
data() {
return {
showElement: false
};
},
ready() {
this.showElement = true;
},
beforeDestroy() {
this.showElement = false;
},
transitions: {
'component': {
enter(el) {
},
leave(el) {
this.showElement = false;
}
},
'element': {
enter(el) {
},
leave(el) {
}
}
}
});
new Vue({
el: '#app',
components: {
pageComponent
},
data: {
show: true
}
});
Upvotes: 3
Views: 4381
Reputation: 1703
You need to use v-show
instead of v-if
because when the parent component is removed, everything attached from him is removed too so the element.leave
transition is never called.
Your example updated: https://codepen.io/anon/pen/PGqxgX
var pageComponent = Vue.extend({
template: '#pageComponent',
data() {
return {
showElement: false
};
},
ready: function () {
this.showElement = true;
},
transitions: {
'component': {
enter(el) {
this.showElement = true;
},
leave(el, done) {
this.showElement = false;
}
}
}
});
new Vue({
el: '#app',
components: {
pageComponent
},
data: {
show: true
},
computed: {
word: function() {
return this.show ? 'hide' : 'show'
}
}
});
html {
font-family: sans-serif;
}
a:hover {
cursor: pointer;
}
.container {
margin-top: 0px;
}
.component {
margin-top: 0;
opacity: 1;
transition: all 2s;
}
.component-enter {
margin-top: -150px;
opacity: 0;
}
.component-leave {
margin-top: -150px;
opacity: 0;
}
.element {
margin-left: 0;
transition: all 2s;
padding: 10px;
}
.element-enter {
margin-left: 300px;
}
.element-leave {
margin-left: 300px;
background: red;
color: white;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/1.0.26/vue.min.js"></script>
<div id="app">
<a @click="show = !show">Click to {{word}} component {{ show }}</a>
<div class="container">
<page-component v-show="show">
</page-component>
</div>
</div>
<script id="pageComponent" type="x-template">
<div class="component" transition="component">
<h1>Component</h1>
<div v-show="showElement" class="element" transition="element">
<p><b>Element</b> {{ showElement }}</p>
<p>Bug on 'leave': <br />this text should be red. <br />and 'element leave' in the console<br />It's not. Why?</p>
</div>
</div>
</script>
Upvotes: 3