An overview of the

There are two kinds of animation: Transition and animation. Vue just uses them in components.

Usage scenarios

  • v-if,v-showAdd animation when displaying hidden components
  • Component switch page switch, add transition animation, fade in and out effect to enhance user experience

transitioncomponent

A built-in vUE component that wraps a DOM node that you want to animate, and only a single element.

How to wrap multiple elements? You need to add v-if and V-else to the attribute tags of the child elements that transition wraps. You need to add a key to the child elements that transition wraps with the same tag name.

transitionRealize the principle of

Add six possible class styles to the DOM element that currently needs to render changes:

  • Initial state of animation:v-enter
  • Animation transition process:v-enter-active
  • Animation transition completed state:v-enter-to

Process: Vue automatically adds the styles for us to switch, we just need to set the categories to switch. Bind a class attribute v-Enter to a DOM element a frame before it moves and then disappear. At the moment before the movement process, the class attributes are changed into V-Enter -active and V-Enter -to. As the movement progresses, the above two class attributes gradually disappear.

Name attribute: The transition header adds a name attribute to distinguish between animations.

<transition name="fade"></transition>
<! -- Vue will change.v-enter to.fade-enter to privatize the animation style -->
Copy the code

Appear property: The animation starts to appear.

<transition appear><transition>
Copy the code

The type attribute: There is an animation that combines transition and animation, and there is a difference in the length of the animation. We can add type to the transition tag to tell Vue which time our animation is based on and avoid the jarring effect of moving up and down. Keep both animations in sync.

transition-groupList the transition

The difference with Transition:

  • transition-groupIt will generate a real onedomNode. The default value isspanThrough thetag="ul"Default switching can be achieved
  • transition-groupThere must bekeyvalue

chestnut

.v-enter./* The initial state of the element before the animation begins */
.v-leave-to{ /* At this point in time, the element finishes animating away from the terminating state */
    opacity: 0;
    transform: translateX(70px)
}
.v-enter-active./* Enter the animation period */
.v-leave-active{ /* Exit animation time */
    transition: all 0.8 s ease;
}

.private-enter..private-leave-to{
    opacity: 0;
    transform: translateY(70px)
}
.private-enter-active..private-leave-active{
    transition: all 0.9 s ease;
}
Copy the code
<div id="app">
    <transition>
        <h1 v-show="flag1">Use the transition class name to animate the effect</h1>
    </transition>
    <br>
    <transition name="private">
        <h1 v-show="flag2">demo</h1>
    </transition>
    <input type="button" value="Button 1" @click="flag1 = ! flag1">
    <input type="button" value="Button 2" @click="flag2 = ! flag2">
</div>
Copy the code
const app = new Vue({
    el: '#app'.data: {
        flag1: true.flag2: true}})Copy the code

Custom style tags

This method is commonly used when using third-party libraries such as animate. CSS, and is often used for exit animations.

Animate. CSS is written based on animation, and its @keyFrame already has an initial and an end value, so all we need to do is set the animate process. For example, leave-active-class=”animate Shake “attribute value animate is required. The following shake animation style can be found in the official site.

chestnuts

.a{
    opacity: 0;
}
.b{
    transition: opacity 10s;
}
.c{
    opacity: 1;
}
Copy the code
<div id="app">
    <transition
        enter-class="a"
        enter-active-class="b"
        enter-to-class="c"
        appear
        leave-active-class="animated shake">
        <h1 v-show="flag">I'm going to sport</h1>
    </transition>
    <button @click="flag = ! flag">change</button>
</div>
Copy the code
const app = new Vue({
    el: '#app'.data: {
        flag: true}})Copy the code

chestnuts

Other uses of animate. CSS:

<div id="app">
    <transition enter-active-class="bounceIn" leave-active-class="bounceOut">
        <h3 v-if="flag">11111111111</h3>
    </transition>
    <input type="button" value="toggle1" @click="flag=! flag">

    <! -- Set the animation duration of entry and departure -->
    <transition enter-active-class="bounceIn" leave-active-class="bounceOut" :duration="1000">
        <h3 v-if="flag1" class="animated">222222222222</h3>
    </transition>
    <input type="button" value="toggle2" @click="flag1=! flag1">

    <! -- Set the animation duration of entry and departure respectively -->
    <transition enter-active-class="bounceIn" leave-active-class="bounceOut" :duration="{enter: 100,leave: 1000}">
        <h3 v-if="flag2" class="animated">333333333333</h3>
    </transition>
    <input type="button" value="toggle3" @click="flag2=! flag2">
</div>
Copy the code

jsThe hook function implements the animation

Eight hook functions

  • @before-enter
  • @enter
  • @after-enter
  • @enter-cancelled
  • @before-leave
  • @leave
  • @after-leave
  • @leave-cancelled

Comprehensive chestnuts

.fade-enter{ /* Defines the start state of the transition, which takes effect before the element is inserted, and the next frame of the element is removed */
    opacity: 0;
}
.fade-enter-active{ /* Define the animation state when the transition takes effect */
    transition: opacity 1s;
}
.fade-enter-to{ /* Define the end state of the transition, remove */ after the transition animation is complete
    opacity: 1;
}
.fade-leave{ 
    opacity: 1;
}
.fade-leave-active{
    transition: opacity 1s;
}
.fade-leave-to{
    opacity: 0;
}

/* ------------ splitter ---------- */
.slide-enter{
    opacity: 0;
    transform: translateY(20px);
}
.slide-enter-active{
    transition: opacity 1s; /* transition和animation结合使用 */
    animation: slide-in 1s ease-out;
}
.slide-enter-to{
    opacity: 1;
    transform: translateY(0px);
}
.slide-leave{
    opacity: 1;
    transform: translateY(0px);
}
.slide-leave-active{
    transition: opacity 1s;
    animation: slide-out 1s ease-out;
    position: absolute;
}
.slide-leave-to{
    opacity: 0;
    transform: translateY(20px);
}
.slide-mode{
    transition: transform 1s;
}
@keyframes slide-in{
    from{
        transform: translateY(20px);
    }
    to{
        transform: translateY(0px); }} @keyframes slide-out{
    from{
        transform: translateY(0px);
    }
    to{
        transform: translateY(20px); }}/* --------- splitter ------- */
.a{
    opacity: 0;
}
.b{
    transition: opacity 10s;
}
.c{
    opacity: 1;
}
Copy the code
<div id="app">
    <! 1 - - - >
    <button @click="show=! show">Click on the</button>
    <br>
    <select v-model="animatedName">
        <option value="fade">Flash transition animation</option>
        <option value="slide">Slide up and down to transition animation</option>
    </select>
    <transition :name="animatedName">
        <div v-show="show">I'm the property binding selection style</div>
    </transition>
    
    <! -- -- -- > 2
    <br>
    <transition name="fade" appear>
        <div v-show="show">I'm privatized tip</div>
    </transition>
    <transition name="slide" appear>
        <div v-show="show">I am a reminder</div>
    </transition>
    
    <!-- 3 -->
    <transition name="slide" appear mode="out-in">
        <div v-if="show">sxw</div>
        <p v-else>iu</p>
    </transition>
    
    <! 4 - - - >
    <transition 
        enter-class="a"
        enter-active-class="b"
        enter-to-class="c"
        appear>
        <div v-show="show">Custom style tags</div>
    </transition>
    
    <!-- 5 -->
    <transition
        enter-active-class="animated bounce"
        leave-active-class="animated shake"
        appear>
        <div v-show="show">Reference third-party libraries</div>
    </transition>
</div>
Copy the code

Enhance the user experience, the above two points of attention:

  • When animating a target element, not only the target element, but all nearby elements have an animation-like effect that drops down
.slide-mode{
    transition: transform 1s;
}
Copy the code
  • For example, if we need to remove the target animation element, we want the target element to leave the document flow completely, and the following elements to be arranged in the empty place
.slide-leave-active{
    transition: opacity 1s;
    animation: slide-out 1s ease-out;
    position: absolute; /* Exit the document stream when leaving */
}
Copy the code

A: chestnutjsThe hook function implements the animation

<button @click="load = ! load">Js implementation of animation</button>
<br>
<transition
    @before-enter="beforeEnter"
    @enter="enter"
    @after-enter="afterEnter"
    @enter-cancelled="enterCancelled"
    
    @before-leave="beforeLeave"
    @leave="leave"
    @after-leave="afterLeave"
    @leave-cancelled="leaveCancelled"
    :css = "false"> 
    <! -- The previous line of code tells Vue that we are not using CSS for animation, reducing the first step for Vue to find CSS -->
    <div v-if="load" style="width: 100px; height: 100px; background-color: red"></div>
</transition>
Copy the code
const vm = new Vue({
    el: '#app'.data: {
        load: false.divWidth: ' '
    },
    methods: {
        beforeEnter(el) {
            console.log(el) // 
      
console.log("beforeEnter") this.divWidth = 10 // Define the div width for each initial animation el.style.width = this.divWidth + 'px' }, enter(el, done) { console.log('enter') done(); // We need to execute the done function to proceed to the other hook functions let round = 1; const timer = setInterval((a)= > { el.style.width = (this.divWidth + round * 10) + 'px' round ++ if(round > 20) { clearInterval(timer) done() } }, 20) }, afterEnter(el) { console.log('afterEnter') el.style.width = '300px' }, enterCancelled(el) { console.log('enterCancelled') }, beforeLeave(el) { console.log('beforeLeave') this.divWidth = '300' el.style.width = this.divWidth + 'px' }, leave(el, done) { console.log('leave') let round = 1 const timer = setInterval((a)= > { el.style.width = (this.divWidth - round * 10) + 'px' round ++ if(round > 20) { clearInterval(timer) done() } }, 20) }, afterLeave(el) { console.log('afterLeave') }, leaveCancelled(el) { console.log('leaveCancelled')}}})Copy the code

Chestnut b:jsThe hook function implements the animation

<div id="app">
    <button @click="addClick">Add a list</button>
    <transition-group tag="ul" name="slide">
        <li 
            v-for="(list,index) in lists"
            @click="removeClick(index)"
            :key="list">
            {{ list }}
        </li>
    </transition-group>
</div>
Copy the code
const vm = new Vue({
    el: '#app'.data: {
        list: [1.2.3]},methods: {
        addClick() {
            const position = Math.floor(Math.random() * this.list.length) // Generate a random number
            this.list.splice(position, 0.this.list.length + 1) // Add location Removed element Number of added elements
        },
        removeClick(index) {
            this.list.splice(index, 1)}}})Copy the code

demo– Small ball added to shopping cart animation implementation

<div id="app">
    <input type="button" value="Add to cart" @click="flag=! flag">
    <transition @before-enter="beforeEnter" @enter="enter" @after-enter="afterEnter">
        <div class="ball" v-show="flag" style="width: 15px; height: 15px; background-color: red; border-radius: 50%;"></div>
    </transition>
</div>
Copy the code
const app = new Vue({
    el: '#app'.data: {
        flag: false
    },
    methods: {
        // el represents the DOM element to animate
        beforeEnter(el) {
            // Before the animation enters, set the starting position of the element to start the animation
            el.style.transform = 'translate(0, 0)'
        },
        enter(el, done) {
            // Set the end state of the ball after it completes the animation
            el.offsetWidth // Force the animation to refresh
            el.style.transform = 'translate(150px, 450px)'
            el.style.transition = 'all 1s ease'
            // Execute done to complete the following hook functions
            done()
        },
        afterEnter(el) {
            AfterEnter is called after the animation is complete
            // Control the display and hide of the ball, skip the second half of the animation directly, and set the flag identifier to false
            this.flag = !this.flag
            el.style.opacity = 0.5}}})Copy the code

demo– List animation – Add delete function

li{
    border: 1px dashed # 999;
    margin: 5px;
    line-height: 35px;
    padding-left: 5px;
    font-size: 12px;
    width: 100%;
}
li:hover{
    background-color: hotpink;
    transition: all 0.8 s ease;
}

.v-enter..v-leave-to{
    opacity: 0;
    transform: translateY(80px);
}
.v-enter-active..v-leave-active{
    transition: all 0.6 s ease;
}
/* List sorting transition, not only can set the entry and exit animations, but also can change positioning */
/* The v-move attribute is required to change the positioning of the element, which is applied */ during the positioning of the element
/* V-move and V-leave-active are used together to make transitions smoother and softer! * /
.v-move{
    transition: all 0.8 s ease;
}
.v-leave-active{
    position: absolute;
}
Copy the code
<div id="app">
    <div>
        <label for="">
            Id:
            <input type="text" v-model="id">
        </label>
        <label for="">
            Name:
            <input type="text" v-model="name">
        </label>
        <input type="button" value="Add" @click="add">
    </div>
    <ul>
        <! TransitionGroup = transitionGroup = transitionGroup = transitionGroup
        <! To animate the elements created by the V-for loop, you must bind each element to a key value.
        <! -- Appear property implements the entry animation when the page is displayed -->
        <transition-group appear tag="ul">
            <li v-for="(item,index) in list" :key="item + index" @click="del(index)">
                {{item.id}} -- {{item.name}}
            </li>
        </transition-group>
    </ul>
</div>
Copy the code
const vm = new Vue({
    el: '#app'.data: {
        id: ' '.name: ' '.list: [{id: 1.name: 'a' },
           { id: 2.name: 'b' },
           { id: 3.name: 'c'}},methods: {
        add() {
            this.list.push( {id: this.id,name: this.name })
            this.id = this.name = ' '
        },
        del(index) {
            this.list.splice(index, 1)}}})Copy the code