2017-01-19 11 views
8

Mam dwa elementy, a widoczność górnego jest kontrolowana przez v-if na prostej wartości logicznej.Elementy przejścia poniżej przeniesionego v-if

transition(name="fade") 
    #element1(v-if="showFirst") 
     p Foo 

#element2 
    p Bar 

Pierwszym elementem jest owinięty w <transition> znacznika dokładnie jak na Vue documentation.

Jednak podczas gdy tworzy się zanikająca animacja, reszta treści na stronie wciąż przeskakuje bardzo wstrząsająco.

Jak utworzyć przejście, które będzie również płynnie przekształcać pozycję wszystkich rodzeństwa, które następują?

A fiddle Demoing this issue.

Odpowiedz

2

Musisz użyć transition-group i wprowadzić swoją dynamiczną div i statycznych div

<transition-group name="fade"> 
    <div v-if="switc" key="dynamic" class="animated"> 
    ... 
    </div> 
    <div key="main-content" class="animated"> 
    ... 
    </div> 
</transition-group> 

i używać tej css klas

.fade-enter, 
.fade-leave-active { 
    opacity: 0; 
    transform: translateY(-10px); 
} 
.fade-leave-active { 
    position: absolute; 
} 

.animated { 
    transition: all 0.5s; 
    /*display: flex;*/ 
    width: 100%; 
} 

Prawdziwą sztuką jest zmienić position do absolute przy wyjeździe, a następnie każda inna treść może zająć właściwą pozycję.

Aby dowiedzieć się więcej na temat Vue animować rzeczy proszę zobaczyć ten FLIP explanation post

I proszę zobaczyć ten skrzypce roboczą https://jsfiddle.net/bjfhth7c/4/

Edycja

Przez pomyłkę zrobiłem ustawiony display: flex; w .animated klasy, że sprawiał, że każdy element wewnętrzny renderował się w dziwny sposób.

Więc teraz, całkowicie usunąć .animate klasę, a zamiast tego zastosować transition: all 0.5s i width:100% do każdego bezpośredniego wewnętrznego elementu .wrapper

moim ostatnim SCSS wygląda następująco:

.wrapper { 
    display: flex; 
    flex-direction: column; 
    >* { 
    transition: all 0.5s; 
    width:100%; 
    }; 
} 

.fade-enter, 
.fade-leave-active { 
    opacity: 0; 
    transform: translateY(-10px); 
} 

.fade-leave-active { 
    position: absolute; 
} 

Flex układ jest rozszerzyć przedmiot , ale w skrócie dla tego konkretnego przypadku, flex-direction: column układa elementy jeden, który poprzednio był mieszkiem.

Jeśli jeden z tych elementów ma pozycję absolutną, zostanie zignorowany w układzie flex, więc wszelkie inne elementy zostaną ponownie rozdzielone na dostępnej przestrzeni.

Proszę zobaczyć ten guide o flexbox i ostatnim working fiddle nadzieję, że to pomaga.

+0

Myślę, że to zdecydowanie najlepsza odpowiedź. Stanowi solidne rozwiązanie dla (możliwej) przyszłej zmiany wymagań. Na przykład, co powiesz na to, że po '# element2' pojawiają się inne elementy? Co powiesz na usunięty element na środku listy? Co powiesz na dodanie nowego elementu między '# element1' i' # element2'? Przejście 'max-height' jest dobrym rozwiązaniem dla konkretnego przypadku, ale jeśli jest to problem z poważnego produktu, poleciłbym go. – Leo

+0

Dzięki @Leo i tak z tym rozwiązaniem można łatwo dodać nowe elementy div przed, po lub między już istniejącymi. Sprawdź ten inny przykład: https://jsfiddle.net/AldoRomo88/q57dtx85/ – AldoRomo88

+0

Dziękuję za odpowiedź, wygląda dobrze, kilka problemów mam do czynienia ze względu na flex wyświetlacza, na przykład chcę mieć przycisk pełnej szerokości, ale ze względu na flex, myślę, że zachowuje się dziwnie, sprawdź [to] (https://jsfiddle.net/q57dtx85/1/). – Saurabh

0

vue js zapewnia różne transition classes, musisz użyć tych poprawnie, aby wygładzić przejście, Próbowałem z twoim przykładem w tym fiddle z niektórymi CSS, spójrz.

.fade-enter-active, .fade-leave-active { 
    transition: all .5s; 
    height: 100px; 
    opacity: 0.5; 
} 
.fade-enter, .fade-leave-to /* .fade-leave-active in <2.1.8 */ { 
    height: 0px; 
    opacity: 0; 
} 

Niektóre dane z dokumentacją:

Istnieje sześć klas wnioskowane może wejść/wyjść przejścia.

  1. v-enter: Stan początkowy dla enter. Dodano element przed wstawieniem, usunięto jedną klatkę po wstawieniu elementu.
  2. v-enter-active: Stan aktywny dla enter. Stosowane podczas całej fazy wchodzenia. Dodano element przed wstawieniem, usunięty po zakończeniu przejścia/animacji. Klasy tej można użyć do zdefiniowania krzywej czasu trwania, opóźnienia i łagodzenia dla wprowadzanego przejścia.
  3. v-enter-to: Dostępne tylko w wersjach> = 2.1.8. Stan zakończenia dla wejścia. Dodano jedną klatkę po wstawieniu elementu (w tym samym czasie usunięto v-enter), usunięto po zakończeniu przejścia/animacji.
  4. v-leave: Stan początkowy dla urlopu. Dodano natychmiast po uruchomieniu przejścia, które zostało usunięte po jednej klatce.
  5. v-leave-active: Aktywny stan dla urlopu. Stosowane podczas całej fazy opuszczania. Dodawany natychmiast po uruchomieniu przejścia na urlop, usuwany po zakończeniu przejścia/animacji. Klasy tej można użyć do zdefiniowania czasu trwania, opóźnienia i krzywej dynamiki dla przejścia kończącego.
  6. v-leave-to: Dostępne tylko w wersjach> = 2.1.8. Stan końcowy dla urlopu. Dodano jedną ramkę po wyzwoleniu przejścia (w tym samym czasie 7. v-leave został usunięty), usunięty po zakończeniu przejścia/animacji.

Można także użyć CSS animations gdzie można dostarczać w różnych fazach transformacji, co będzie aĹ css aby dokonać przejścia bardziej gładka, jak śledzenie i demo fiddle:

.fade-enter-active { 
    animation: bounce-in .5s; 
} 
.fade-leave-active { 
    animation: bounce-out .5s; 
} 
@keyframes bounce-in { 
    0% { 
    height: 5px; 
    } 
    30% { 
    height: 30px; 
    } 
    50% { 
    height: 50px; 
    } 
    100% { 
    height: 100px; 
    } 
} 
@keyframes bounce-out { 
    0% { 
    height: 90px; 
    } 
    50% { 
    height: 50px; 
    } 
    100% { 
    height: 0px; 
    } 
} 
+0

Dzięki, ale to wymaga określenia wysokości w CSS dla elementu; w moim przypadku nie jest to możliwe, ponieważ element może mieć dowolną wysokość ze względu na jego zawartość. –

+0

@EmphramStavanger Czy potrafisz stworzyć swoją skrzynkę w moim skrzypcach, aby móc się nią bawić. – Saurabh

+0

Tutaj jesteś; https://jsfiddle.net/bjfhth7c/2/ –

1

Zamiast tego możesz użyć animacji slideDown/slideUp. Aby to osiągnąć, nie musisz znać wysokości elementu ślizgowego, zasady transformacji max-height wyjaśnił there.

W rezultacie spowoduje to animowane przesuwanie elementów poniżej celu.

Sprawdź mój example na podstawie Twojego skrzypce.

+0

Kiedy zaczynam używać '.fade-leave-active', dlaczego animacja przestaje działać, gdy ponownie ukryję div, zobacz [demo] (https: // jsfiddle. net/yzwh0od7/1 /) – Saurabh

+0

Ponieważ klasa "* -leave-active' stosuje się do elementu docelowego podczas całego cyklu animacji, ale musisz kontrolować tylko wartości początkowe i końcowe, dlatego też załączam przykład. Sprawdź sekcję klas przejściowych w dokumentacji - https://vuejs.org/v2/guide/transitions.html#Transition-Classes –

+0

Ta animacja dwukierunkowa nie jest możliwa przy Vue mniejszym niż 2.1.8, gdy .fade-leave-to nie było klasy? – Saurabh