-1

Based on this answer, I'm trying to create a Vue slideToggle component using transition.

The slideToggle is a classic paradigm in height animation. I've been successful so far...

I don't want to set a fixed max-height or height, I want the height to be dynamic.

My animation is working properly when displaying and hiding. The problem is in canceling while displaying or hiding.

How to handle the @enter-cancelled and the @leave-cancelled hooks? I'm new to vue transitions :)

I put my code inside this CodeSandBox: https://codesandbox.io/s/vue-template-3b7oj

0

3 Answers 3

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.

Sign up to request clarification or add additional context in comments.

Comments

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.

Comments

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.