Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reference lost on leave transition hook #3481

Closed
stephanedemotte opened this issue Aug 19, 2016 · 11 comments
Closed

Reference lost on leave transition hook #3481

stephanedemotte opened this issue Aug 19, 2016 · 11 comments
Labels

Comments

@stephanedemotte
Copy link

Vue.js version

2.0.0-rc.2

Vue-router version

2.0.0-rc.3

Reproduction Link

repro

Steps to reproduce

open the console, click on nav, check the log

What is Expected?

On Enter transition hook, the log to the reference "page" (this.$refs.page)
On Leave transition hook, the log to the reference "page" (this.$refs.page)

What is actually happening?

On Enter => the log is correct.
On Leave => this.$refs.page is undefined

@stephanedemotte stephanedemotte changed the title Ref lost on leave transition hook Reference lost on leave transition hook Aug 19, 2016
@posva
Copy link
Member

posva commented Aug 19, 2016

I simplified the repro a bit: https://jsfiddle.net/wfzzcrx6/6/ vue-router is unrelated to the issue 😄

PS: You don't need Vue.use(VueRouter) when including vue-router with a script tag, it'll call it for you. You still need it when using a module bundler

@stephanedemotte
Copy link
Author

stephanedemotte commented Aug 20, 2016

Since the fix, with mode="false" and mode="in-out" the leave hook is call from the next component instead of the current. Wait for a pre-release to make a online repro.
Thanks

@yyx990803
Copy link
Member

@stephanedemotte unfortunately there's no guarantee about the refs update order in relation to the transition hooks when the transition is happening simultaneously, because in the vnode patching process, enter happens first and remove happens next. When the incoming component enters, it already replaces the current ref.

In general I don't think relying on refs inside transition hooks is a good idea - maybe it's better to explain what you are trying to achieve and why is it necessary.

@stephanedemotte
Copy link
Author

stephanedemotte commented Aug 20, 2016

I try to have different transition between my page with transtition and vue-router

here the link where i ask for help :)

With vue 1.0 with your help i've got it.
But we try to update our kickstart to vue 2.0, and keep this logic.

We really need to get different "complex" transition, to be able to create some cool SPA like noize or 1700 laposte
We've done this website with vue 1.0

In our transition we need the reference to the current component, to get some data, get $router name etc...

You can see in noize, the transition is different everytime, if you go to collection from home we have one, if you leave collection detail to return to collection it's a different one.

The idea it's to let each page component create it's own transition, with that, the component can check the route, get some width, height etc....

Thanks again !

@stephanedemotte
Copy link
Author

The next step it's to let each components have its own transition.

The page component can wait for promisesAll, and when all component have finish. The component page can lunch done function.

With that i think we can create awesome robust SPA.

@yyx990803
Copy link
Member

FYI you can place <transition> inside child component as its root - this allows you to have different transitions for each child component.

@stephanedemotte
Copy link
Author

stephanedemotte commented Aug 20, 2016

@yyx990803 I have try that. But the mode="out-in" dont work with the transition inside the view router :/

@stephanedemotte
Copy link
Author

@yyx990803 i have to deal with ?

@max-schu
Copy link

is there a solution for this already i didnt manage to find?
if using the transition as root in the child component the router doesnt wait for "done" and executes the route before the leave transition was finished.

@bdrtsky
Copy link

bdrtsky commented Feb 14, 2020

Kinda crazy how many things I need to change in my code just to adjust to this quirk.

@rhernandog
Copy link

rhernandog commented Aug 20, 2022

OK, so I found a couple of ways to make this work. One is using regular selectors at the start of the leave hook. Another is to use an object and set the refs in that object. Something like this:

<template>
  <Transition
    @enter="enterAnimationHandler"
    @leave="leaveAnimationHandler"
    :css="false"
  >
    <div v-if="show">
      <div ref="elementOne"></div>
      <div ref="elementTwo"></div>
    </div>
  </Transition>
</template>
<script setup>
  import { ref } from "vue";
  import gsap from "gsap";

  const elementOne = ref(null);
  const elementTwo = ref(null);
  const myRef = {};

  const enterAnimationHandler = (_, done) => {
    document.body.classList.add("overflow-hidden");
    myRef.elementOne = elementOne.value;
    myRef.elementTwo = elementTwo.value;
    gsap
      .timeline({ onComplete: done  })
      .to(elementOne.value, { ... }, 0)
      .to(elementTwo.value, { ... }, 0.05)
      .play();
  };
  function leaveAnimationHandler(_, done) {
    gsap
      .timeline({ onComplete: done  })
      .to(myRef.elementOne, {...})
      .to(myRef.elementTwo, {...})
      .play();
  }
</script>

Of course the latter is not a good approach if the elements with the ref attribute are replaced. In my case they're never re-rendered, so it's safe, but if they do change, the best approach is to use a selector to traverse through the parent element inside the transition tag and look for the elements using an id or class selector.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

6 participants