vuejs / vue

This is the repo for Vue 2. For Vue 3, go to https://github.com/vuejs/core
http://v2.vuejs.org
MIT License
207.89k stars 33.69k forks source link

Аn unexpected behaviour when using <transition> with a Vue component. #4921

Open antixrist opened 7 years ago

antixrist commented 7 years ago

Vue.js version

2.1.10

Reproduction Link

https://jsfiddle.net/bhrztdjn/4/

Steps to reproduce

Click on "Toggle" button.

What is Expected?

Transitions for a component should have the same behavior as transitions applied to HTML element.

What is actually happening?

A CSS transition works fine with an HTML element with both directive - v-if and v-show (as declared in docs). But for the component, which has a directive v-show on its root element the transition isn't applied on entering and leaving states. And for the component, which has a directive v-if on its root element the transition isn't applied on leaving state.

posva commented 7 years ago

Thanks for opening the issue. Even though I'd add the V-if/v-show in the parent template (https://jsfiddle.net/posva/bhrztdjn/5/), the behaviour is not consistent and at the very least docs should be updated to add a warning about it.

Why do you add the visible prop, are you using it inside of the component for other things? Do you mind sharing a bit more about the component itself?

antixrist commented 7 years ago

Why do you add the visible prop, are you using it inside of the component for other things?

@posva, yes. For example it needed in modal component. Watcher on the visible prop allow to do some internal things like add/remove event listeners to body (for Esc behavior), add/remove some html classes to <html> and etc. It difficult without visible prop.

Plasmatium commented 7 years ago

@posva , is this the expected behavior? Is the tag allowed transition only if follow <transition> tag @antixrist , I think maybe we can pass the transition type intention into template.

template: `
<transition :name='transtype'>
<div v-show="visible">I am a component with v-show directive (inside transition)</div>
</transition>
`,
props: [ 'visible', 'transtype']

Here is the code: jsfiddle

gebilaoxiong commented 7 years ago

@antixrist

Dear antixrist : )

I think this is not a good idea

because transition is a component, cmp-v-if(child component) is also a component

it looks like you want to use child component props to control the parent

antixrist commented 7 years ago

@gebilaoxiong nope. Child component can take value prop for control it from parent by v-model and can emit input event. So only parent component decides about change state and the children is aware about this state.

Here is my modal component with example. In this component data flow is not broken, but I still can not manage transitions outside of the <modal> component. Although the documentation says otherwise (which is confirmed by a @posva):

Vue provides a transition wrapper component, allowing you to add entering/leaving transitions for any element or component in the following contexts:

  • Conditional rendering (using v-if)
  • Conditional display (using v-show)
  • Dynamic components
  • Component root nodes
Nartub600 commented 6 years ago

I had a transition which worked with v-if but not with v-show. I had to resort to this solution https://medium.com/vuejs-tips/css-only-v-show-fade-animation-6f7818fdff4 for it to work

Black-Horse commented 6 years ago

I am facing the same problem @antixrist describes in the initial post.

My child component holds data that, among other things, contains whether it should be visible (mutableDisplayData.visible). The child component is wrapped inside a <transition> and arranged at a for the child unknown position in the parent. Might be on the left, might be on the right. Depending on the status of mutableDisplayData.visible, this should be animated / transitioned. The parent needs to control where the child is positioned and the transition must be chosen according to the position. This is why the transition needs to be in the parent.

This is how the structure looks (simplified)

<transition>
      <child>
           <template>
                <div v-if="mutableDisplayData.visible">
                        ...
                </div>
           </template>
      <child>
 </transition>

The enter animation runs fine. On leave, it is immediately removed from the dom which I think is a bug. If I move the v-if directly to <child> it would work. But I cannot do that because I do not know about the visibility of the child in the parent (in my special case).

Any ideas on how to achieve what I need?

yavuzsecer88 commented 5 years ago

It appears that this issue is back. Im having the same warningson version 2.6.6

WofWca commented 4 years ago

I think

transition behavior is inconsistent for v-show/v-if and components/elements

(or something like that) would be a better title. Would make it easier to find it.

RajithaKumara commented 3 years ago

Hi @antixrist Did you managed the modal component? If so, I want some help

Update: Seems no issues Vue 3. In my case, leave-to transition not worked because of :hover styles applied.