Does the "before" hook trigger a render when leveraging transition hooks in a render function?

Viewed 52

I am trying to create a movement transition within a render function using appear hooks. I thought that putting initial state of the transition within the beforeAppear hook and then setting the finalized state in the appear hook would cause an element to be enough for a transition to occur.

However, what seems to be happening is that the style that I set in the beforeAppear either never renders, or is overwritten in the appear hook before the browser knows that it should transition.

Below is an example of what I am trying to accomplish. Using Vue.nextTick() does not give me what I was hoping. However, I do see that using a setTimeout() will give me what I am effectively looking for, but I thought that this was the built-in functionality of the appear hook considering the docs Transition Classes:

  1. v-enter: Starting state for enter. Added before element is inserted, removed one frame after element is inserted.

  2. v-enter-active: Active state for enter. Applied during the entire entering phase. Added before element is inserted, removed when transition/animation finishes. This class can be used to define the duration, delay and easing curve for the entering transition.

I understand that these are for the classes that are applied to the element, but don't these map 1:1 with the hooks?

const app = new Vue({
  el: "#app",
  render(h) {

    // Just hooks
    const transitionTestJustHooks = h("transition", {
      props: {
        css: false,
        appear: ""
      },
      on: {
        beforeAppear(el) {
          console.log("before-appear");
          el.style.position = "absolute";
          el.style.transition = "left 2s ease";
          el.style.top = "0em";
          el.style.left = "20px";
        },
        appear(el, done) {
          console.log("appear");
          el.style.left = "200px";
          done();
        }
      }
    }, [h("div", "just-hooks")]);

    // Vue.nextTick()
    const transitionTestNextTick = h("transition", {
      props: {
        css: false,
        appear: ""
      },
      on: {
        beforeAppear(el) {
          console.log("before-appear");
          el.style.position = "absolute";
          el.style.transition = "left 2s ease";
          el.style.top = "1em";
          el.style.left = "20px";
        },
        appear(el, done) {
          console.log("appear");
          Vue.nextTick(() => {
            el.style.left = "200px";
            done();
          });
        }
      }
    }, [h("div", "Vue.nextTick()")]);

    // setTimeout()
    const transitionTestSetTimeout = h("transition", {
      props: {
        css: false,
        appear: ""
      },
      on: {
        beforeAppear(el) {
          console.log("before-appear");
          el.style.position = "absolute";
          el.style.transition = "left 2s ease";
          el.style.top = "2em";
          el.style.left = "20px";
        },
        appear(el, done) {
          console.log("appear");
          setTimeout(() => {
            el.style.left = "200px";
            done();
          });
        }
      }
    }, [h("div", "setTimeout")]);

    return h("div", [
      transitionTestJustHooks,
      transitionTestNextTick,
      transitionTestSetTimeout
    ]);
  }
});
<script src="https://unpkg.com/vue@2.6.10/dist/vue.min.js"></script>

<div id="app"></div>

0 Answers
Related