[Vuejs]-Vue Transition – JavaScript hooks

3πŸ‘

I don’t know if this helps you, but try this:

declare a new variable:

data() {
  return {
    height: null,
    toggling: false
  };
},

when the open or close function start, verify if toggling is true, if yes, just cancel, like this:

    enter(el) {
      if (this.toggling) return;
      this.toggling = true;
      this.height = el.offsetHeight;

      el.style.overflow = "hidden";
      el.style.height = 0;
      el.style.paddingTop = 0;
      el.style.paddingBottom = 0;
      el.style.marginTop = 0;
      el.style.marginBottom = 0;

      setTimeout(() => {
        el.style.transitionProperty = `height, margin, padding`;
        el.style.transitionDuration = this.duration + "ms";
        el.style.height = this.height + "px";
        el.style.removeProperty("padding-top");
        el.style.removeProperty("padding-bottom");
        el.style.removeProperty("margin-top");
        el.style.removeProperty("margin-bottom");
        this.toggling = false;
      });
    },

Will be something like this:
https://codesandbox.io/s/vue-template-78n7t?fontsize=14

Maybe i broke your code, sorry, but will you get the idea.

1πŸ‘

As per the offical documentation Javacript transition hooks
the @leave-cancelled is only available with v-show, where are in your sample code you are using v-if, if you change this you will be able to capture the @leave-cancelled hook,@leave-cancelled and @enter-cancelled are triggered when enter or leave are interrupted, say you press the toggle button while opening as well as pressing the button while its closing.

0πŸ‘

Vue-Transition-Cancel

tl;dr


  • leave event cancels not yet called enter
  • enter cancels not yet called leave

cancel state is stored in

  • el._enterCb.cancelled

  • el._leaveCb.cancelled


analysis


Consider:

const cb = el._enterCb = once(() => {
    if (expectsCSS) {
      removeTransitionClass(el, toClass)
      removeTransitionClass(el, activeClass)
    }
    if (cb.cancelled) {
      if (expectsCSS) {
        removeTransitionClass(el, startClass)
      }
      enterCancelledHook && enterCancelledHook(el)
    } else {
      afterEnterHook && afterEnterHook(el)
    }
    el._enterCb = null
  })

source: _enterCb

So a naive solution to cancel @enter is

el => {el._enterCb.cancelled = true; done()}


This is what actually happens when one triggers leave

// call enter callback now
  if (isDef(el._enterCb)) {
    el._enterCb.cancelled = true
    el._enterCb()
  }

source: leave


Same applies to:

  const cb = el._leaveCb = once(() => {
    if (el.parentNode && el.parentNode._pending) {
      el.parentNode._pending[vnode.key] = null
    }
    if (expectsCSS) {
      removeTransitionClass(el, leaveToClass)
      removeTransitionClass(el, leaveActiveClass)
    }
    if (cb.cancelled) {
      if (expectsCSS) {
        removeTransitionClass(el, leaveClass)
      }
      leaveCancelled && leaveCancelled(el)
    } else {
      rm()
      afterLeave && afterLeave(el)
    }
    el._leaveCb = null
  })

source: _leaveCb


One can check for possible assignments:

https://github.com/vuejs/vue/search?q=_leaveCb&unscoped_q=_leaveCb

Leave a comment