简体   繁体   中英

Vue child component leave transition callback not working

I defined a Parent component which have a Child component, both components have dynamic transitions with leave callbacks defined as outro , the problem is that when Parent component gets destroyed its outro method works fine but its Child component outro method never gets fired. Is there anyway to accomplish this and keep Child component reusable and decoupled? Demo .

App template:

<div id="app">
  <parent v-if="showContainer"></parent>
  <button @click="showContainer = !showContainer">
    Toggle Container
  </button>
</div>

Javascript:

// ISSUE:
// 1. Parent removes child component in its `outro` method
// 2. Child `outro` method never gets called

var Child = {
    template: `
    <transition
        :css="false"
        appear
        @appear="intro"
        @enter="intro"
        @leave="outro"
    >
        <div class="Child"></div>
    </transition>`,
    methods: {
        intro: function (el, done) {
            TweenLite.fromTo(el, 0.5,
                { y: '100%' },
                { y: '0%', delay: 0.5, onComplete: done })
        },
        outro: function (el, done) {
            // 2 <===
            TweenLite.to(el, 0.5,
                { y: '100%', onComplete: done })
        },
    },
}

var Parent = {
    template: `
    <transition
        :css="false"
        appear
        @appear="intro"
        @enter="intro"
        @leave="outro"
    >
        <div class="Parent">
            <div ref="inner" class="Parent__inner"></div>
            <child v-if="showChild"></child>
        </div>
    </transition>`,
    components: {
        Child: Child,
    },
    data() {
        return {
            showChild: true,
        }
    },
    methods: {
        intro: function (el, done) {
            TweenLite.fromTo(this.$refs.inner, 0.5,
                { y: '100%' },
                { y: '0%', delay: 0.25, onComplete: done })
        },
        outro: function (el, done) {
            // 1 <===
            // Setting `showChild` to `false` should remove Child component
            // and trigger its `outro` method ¿?
            this.showChild = false
            TweenLite.to(this.$refs.inner, 0.5,
                { y: '100%', delay: 0.25, onComplete: done })
        },
    },
}

new Vue({
    el: '#app',
    data() {
        return {
            showContainer: true,
        }
    },
    components: {
        Parent: Parent,
    },
})

Pretty sure it's not possible this way. Even when using CSS transitions, the parent still need to control the child's transition out. We'd need a disappear prop on Transition component :p

Maybe you won't love this solution but, in the parent's outro, you can call this.$refs.child.outro(this.$refs.child.$el)

see corrected demo

  1. Use v-show directive. See compare v-if vs f-show

     <parent v-show="showContainer"></parent>
  2. child elements need self-controller and binding with properties

  • add v-if="showChild" in <div class="Child"></div>

  • create props in child

    props: { showChild: { type: Boolean, default: true } },

  • binding props in parent

     <child :showChild="showChild"></child>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM