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

Function wiring breaks for components that show/hide slot content using v-if #3518

Closed
analog-nico opened this issue Aug 25, 2016 · 7 comments
Labels

Comments

@analog-nico
Copy link

Vue.js version

2.0.0-rc.3

Reproduction Link

http://codepen.io/analog-nico/pen/dXBRBG

Steps to reproduce

  1. Click the link "Open popup using v-if"
  2. A badly designed popup opens
  3. Click the "Close" link
  4. For this first time the popup closes successfully
  5. Click the link "Open popup using v-if" again
  6. The popup opens again
  7. Click the "Close" link

What is Expected?

  • Again, the popup closes successfully

What is actually happening?

  • Vue fails to call an internal function that got missing.
  • The closePopupUsingVIf function attached to the "Close" link's click event never gets called.
  • The popup does not close.

For reference the codepen contains the exact same implementation of the popup with the only difference that it uses v-show instead of v-if to show/hide the popup. v-show works perfectly.

@fnlctrl
Copy link
Member

fnlctrl commented Aug 25, 2016

The problem is that you are using v-if on component's root element inside its template.
Since the component itself is destroyed when v-if goes to false, its show() function cannot be called.
Related issue: #3455

I guess vue should prohibit using v-if on component's root element..

@analog-nico
Copy link
Author

Unfortunately, using v-if on an element other than the root element still doesn't work. See: http://codepen.io/analog-nico/pen/mEkraL

@LinusBorg
Copy link
Member

LinusBorg commented Aug 25, 2016

Using $refs for this won't work, as explained by @fnlctrl due to issue #3455, but I would say this is not a recommended pattern anyway.

I would rather:
a) pass a is-shown prop to the component, (https://jsfiddle.net/Linusborg/rwa5cfdm/) or
b) use v-if on the component itself (https://jsfiddle.net/Linusborg/rwa5cfdm/1/)

if the popup component will have its own controls, i.e. a close button, $emit() an event from it and let the parent listen with @event="handler" on the component - then the parent can change the state value.

This has several advantages:

  • the parent knows about weither or not the popup is shown
  • We don't need to use tight coupling to the child components via $ref in you JS code.
  • the parent stays in control of when to actually show and hide the popup.

@LinusBorg
Copy link
Member

Closing this because #3455 takes care of this.

@fnlctrl
Copy link
Member

fnlctrl commented Aug 25, 2016

@LinusBorg The reproduction is already using rc.3, which was supposed to fix #3455 (release notes https://github.com/vuejs/vue/releases/tag/v2.0.0-rc.3), so I guess there's still some edge case not covered.

@prog-rajkamal
Copy link

wait, isn't it invalid component, as v-if version will have no root element when isShown is false? From what I know, a component should resolve to a root instance(or a fragment instance), but in this case there is not even a single element when isShown is false.

@analog-nico
Copy link
Author

@prog-rajkamal That is a valid point which @fnlctrl also mentioned in his first response. However, the bug still occurs if I move v-if to a child div. See my updated codepen.

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

5 participants