Vue animation (transition)

1. Implementation principle

When inserting, updating, and removing DOMelements, add a style class name to the element at an appropriate time, and CSSuse it with the style to achieve animation effects.

In layman's terms, it is to wrap the element to be animated DOMwith transitiona tag. Before, during, and after the movement of this html element, different elements vuewill be added , and then combined with the style to achieve animation effects.DOMclassCSS

Example:

<template>
  <div>
    <button @click="bol = !bol">隐藏/显示</button>
    <!-- Vue 的内置动画标签 transition -->
    <transition>
      <!-- 只能包含 1 个元素 -->
      <h1 v-show="bol">组件动画效果</h1>
      <!-- 需要设置 v-show / v-if 属性控制元素的显示 -->
    </transition>
  </div>
</template>

<script>
export default {
      
      
  name: "TestDemo",
  data() {
      
      
    return {
      
       bol: true };
  },
};
</script>

<style>
/* 进入:始状态 */
.v-enter {
      
      
  transform: translateX(-100%);
  color: red;
}
/* 进入:末状态 */
.v-enter-to {
      
      
  transform: translateX(0);
  color: yellow;
}
/* 进入动画 */
.v-enter-active {
      
      
  transition: 10s;
  color: linear-gradient(red,yellow);;
}

/* 离开:始状态 */
.v-leave {
      
      
  transform: translateX(0);
}
/* 离开:末状态 */
.v-leave-to {
      
      
  transform: translateX(-100%);
}
/* 离开动画 */
.v-leave-active {
      
      
  transition: 1s;
}
</style>

Two, transition label

  • VueThe built-in animation tags:transition
  • transitionA tag can only contain 1 element; if multiple elements are written inside, only the first one will take effect
  • transitionWrapped tags require settings v-show/ v-ifproperties to control the display of the element

3. The class name corresponding to the animation CSS style

  • Enter: .v-enterstart state, .v-enter-toend state, .v-enter-activeenter animation
  • Leave: .v-leavestart state, .v-leave-toend state, .v-leave-activeleave animation
  • .v-enter, .v-leaveDefine the initial state of the animation, in which you can define the initial position, color, font, etc.
  • .v-enter-to, defines the final state of the animation, the definition of these two classes should be consistent with the DOM class, otherwise it will instantly change from the style of , to the style of DOM .v-leave-toafter the animation ends (instance 1, example 2).v-enter-to.v-leave-to
  • .v-enter-active, .v-leave-activeDefine the gradient rules of the animation, for example, if it is a position gradient, it will define the time and path of the gradient; if it is a color gradient, it will define the color-related gradient rules

3.1 Example 1

will fade from red to yellow

<template>
    <div>
      <button @click="bol = !bol">隐藏/显示</button>
      <transition>
        <h1 v-show="bol" class="demo">组件动画效果</h1>
      </transition>
    </div>
  </template>
  
  <script>
  export default {
      
      
    name: "TestDemo",
    data() {
      
      
      return {
      
       bol: true };
    },
  };
  </script>
  
  <style>
  .v-enter-active,
  .v-leave-active {
      
      
    transition: 10s !important;
    color: linear-gradient(red,yellow) !important;
  }

  .demo {
      
      
    color: yellow;
  }

  .v-enter,
  .v-leave-to {
      
      
    transform: translateX(-50%);
    color: red;
  }
  </style>

3.2 Example 2

will fade from red to yellow and then instantly to black

<template>
  <div>
    <button @click="bol = !bol">隐藏/显示</button>
    <transition>
      <h1 v-show="bol" class="demo">组件动画效果</h1>
    </transition>
  </div>
</template>
  
  <script>
export default {
      
      
  name: "TestDemo",
  data() {
      
      
    return {
      
       bol: true };
  },
};
</script>
<style>
.v-enter,
.v-leave-to {
      
      
  transform: translateX(-50%);
  color: red;
}

.v-enter-to,
.v-leave {
      
      
  transform: translateX(0);
  color: yellow;
}

.v-enter-active,
.v-leave-active {
      
      
  transition: 10s !important;
  color: linear-gradient(red, yellow) !important;
}
</style>

4. Properties of the transition tag

4.1 name attribute

Used to automatically generate CSS animation class names

  • If transitionthe label element does not set namethe attribute, the corresponding animation class name isv-XXX
  • If the attribute is set name, the corresponding animation class name is属性值-XXX
  • When there are multiple tansitiontags, we can specify different animation effects namefor each tag through the attributetransitionCSS

4.2 appear attribute

Display animation in effect at the beginning

4.3 mode attribute

  • in-out: The new element transitions first, and the current element transitions away after completion
  • out-in: The current element transitions first, and after completion, the new element transitions into

4.4 Examples

<template>
  <div>
    <button @click="bol = !bol">隐藏/显示</button>
    <!-- Vue 的内置动画标签 transition -->
    <transition name="test" appear>
      <!-- 只能包含 1 个元素 -->
      <h1 v-show="bol">组件动画效果</h1>
      <!-- 需要设置 v-show / v-if 属性控制元素的显示 -->
    </transition>
  </div>
</template>

<script>
export default {
      
      
  name: "TestDemo",
  data() {
      
      
    return {
      
       bol: true };
  },
};
</script>

<style>
.test-enter,
.test-leave-to {
      
      
  transform: translateX(-50%);
  color: red;
}

.test-enter-to,
.test-leave {
      
      
  transform: translateX(0);
  color: yellow;
}

.test-enter-active,
.test-leave-active {
      
      
  transition: 10s !important;
  color: linear-gradient(red,yellow) !important;
}
</style>

Five, transition-group label

  • transitionA label can only contain 1 element, and transition-groupa label can contain multiple elements
  • transition-groupThe elements in the tag need to set keythe attribute as the unique identifier of the current element
  • Other than that, other uses are transitionthe same as tags
<template>
  <div id="app">
    <button @click="isEditing = !isEditing">切换</button>
    <transition-group appear>
      <h1 v-if="isEditing" key="save">Save</h1>
      <h1 v-if="!isEditing" key="edit">Edit</h1>
    </transition-group>
  </div>
</template>

<script>
export default {
      
      
  name: "TestDemo",
  data() {
      
      
    return {
      
       isEditing: true };
  },
};
</script>

<style>
h1 {
      
      
  transition: 3s;
  position: absolute;
}
.v-leave {
      
      
  opacity: 1;
}
.v-leave-to {
      
      
  opacity: 0;
}
.v-enter {
      
      
  opacity: 0;
}
.v-enter-to {
      
      
  opacity: 1;
}
</style>

6. JavaScript hook function

      @before-enter="beforeEnter"
      @enter="enter"
      @after-enter="afterEnter"
      @enter-cancelled="enterCancelled"
      @before-leave="beforeLeave"
      @leave="leave"
      @after-leave="afterLeave"
      @leave-cancelled="leaveCancelled"
  methods: {
    
  // --------
  // 进入中
  // --------

  beforeEnter: function (el) {
    console.log('beforeEnter');
    console.log(el);
  },
  // 当与 CSS 结合使用时
  // 回调函数 done 是可选的
  enter: function (el, done) {
    console.log('enter');
    console.log(el);
    done()
  },
  afterEnter: function (el) {
    console.log('afterEnter');
    console.log(el);
  },
  enterCancelled: function (el) {
    console.log('enterCancelled');
    console.log(el);
  },

  // --------
  // 离开时
  // --------

  beforeLeave: function (el) {
    console.log('beforeLeave');
    console.log(el);
  },
  leave: function (el, done) {
    console.log('leave');
    console.log(el);
    done()
  },
  afterLeave: function (el) {
    console.log('afterLeave');
    console.log(el);
  },
  // leaveCancelled 只用于 v-show 中
  leaveCancelled: function (el) {
    console.log('leaveCancelled');
    console.log(el);
  }
  },

Seven, Vue implements various methods of animation

7.1 transition

<template>
  <div>
    <button @click="bol = !bol">隐藏/显示</button>
    <transition name="fade">
      <p v-if="bol">hello</p>
    </transition>
  </div>
</template>

<script>
export default {
      
      
  name: "TestDemo",
  data() {
      
      
    return {
      
       bol: true };
  },
};
</script>

<style scoped>
.fade-enter-active,
.fade-leave-active {
      
      
  transition: all 3s;
}
.fade-enter,
.fade-leave-to {
      
      
  opacity: 0;
  width: 100px;
}
p {
      
      
  border: 1px solid red;
  width: 300px;
}
</style>

7.2 animation + @keyframes

<template>
  <div>
    <button @click="bol = !bol">隐藏/显示</button>
    <transition name="bounce">
      <p v-show="bol" class="demo">组件动画效果</p>
    </transition>
  </div>
</template>

<script>
export default {
      
      
  name: "TestDemo",
  data() {
      
      
    return {
      
       bol: true };
  },
};
</script>
<style>
.bounce-enter-active {
      
      
  animation: bounce-in 5s;
}
.bounce-leave-active {
      
      
  animation: bounce-in 5s reverse;
}
@keyframes bounce-in {
      
      
  0% {
      
      
    transform: scale(0);
  }
  50% {
      
      
    transform: scale(1.5);
  }
  100% {
      
      
    transform: scale(1);
  }
}
</style>

7.3 animate.css

  1. Install:npm install animate.css
  2. Import the style library:import "animate.css"
  3. Add attributes to the specified transitiontagnameanimate_animate、animate__bounce
  4. Configure enter-active-classthe attribute, specify the entry animation: pick an entry style value in the style library as enter-active-classthe attribute value
  5. Configure leave-active-classthe property to specify the exit animation: pick an exit style value in the style library as leave-active-classthe property value
<template>
  <div>
    <button @click="bol = !bol">隐藏/显示</button>
    <transition
      name="animate__animated animate__bounce"
      enter-active-class="animate__bounceIn"
      leave-active-class="animate__bounceOut"
    >
      <p v-show="bol" name="animate_animate">组件动画效果</p>
    </transition>
  </div>
</template>

<script>
import "animate.css";
export default {
      
      
  name: "TestDemo",
  data() {
      
      
    return {
      
       bol: true };
  },
};
</script>

7.4 JavaScript hooks

  1. When using only JavaScripttransitions, must use callbacks in enterand . Otherwise, they are called synchronously and the transition completes immediately.leavedone
  2. It is recommended that for element additions that only use JavaScripttransitions v-bind:css="false", the detection of Vueis skipped CSS. This also avoids effects during the transition CSS.

7.5 Velocity.js

  1. Install:npm install velocity-animate
<template>
  <div id="app">
    <button @click="show = !show">显示/隐藏</button>
    <br />
    <transition
      v-on:before-enter="beforeEnter"
      v-on:enter="enter"
      v-on:leave="leave"
      v-bind:css="false"
    >
      <p v-show="show">hello</p>
    </transition>
  </div>
</template>

<script>
import Velocity from "velocity-animate";

export default {
      
      
  name: "App",
  data: function () {
      
      
    return {
      
      
      show: true,
    };
  },
  methods: {
      
      
    beforeEnter: function (el) {
      
      
      el.style.opacity = 0;
    },
    enter: function (el, done) {
      
      
      Velocity(
        el,
        {
      
      
          rotateZ: "0deg",
          translateY: "0px",
          translateX: "0px",
          opacity: 1,
        },
        {
      
       complete: done }
      );
    },
    leave: function (el, done) {
      
      
      Velocity(
        el,
        {
      
      
          rotateZ: "45deg",
          translateY: "30px",
          translateX: "30px",
          opacity: 0,
        },
        {
      
       complete: done }
      );
    },
  },
};
</script>

7.6 Transitions between multiple elements

<template>
  <div id="example-2">
    <transition name="fade" mode="out-in">
      <button v-if="isEditing" key="save" @click="isEditing = !isEditing">
        Save
      </button>
      <button v-else key="edit" @click="isEditing = !isEditing">Edit</button>
    </transition>
  </div>
</template>

<script>
export default {
      
      
  name: "TransitionTest",
  data() {
      
      
    return {
      
      
      name: "TransitionTest",
      isEditing: false,
    };
  }
};
</script>
<style scoped>
.fade-enter-active,
.fade-leave-active {
      
      
  transition: all 1s;
}
.fade-enter {
      
      
  opacity: 0;
  transform: translateX(50px);
}
.fade-leave-to {
      
      
  opacity: 0;
  transform: translateX(-50px);
}

#example-2 {
      
      
  position: relative;
  padding: 100px;
}
#example-2 button {
      
      
  position: absolute;
}
</style>

7.7 Transition of Multiple Components

<template>
  <div id="transition-components-demo">
    <button @click="view = 'VA'">a</button>
    <button @click="view = 'VB'">b</button>
    <transition name="component-fade" mode="out-in">
      <component v-bind:is="view"></component>
    </transition>
  </div>
</template>

<script>
import VA from "./VA.vue";
import VB from "./VB.vue";

export default {
      
      
  name: "TransitionTest",
  data() {
      
      
    return {
      
      
      view: "VA",
    };
  },
  components: {
      
      
    VA,
    VB,
  },
};
</script>
<style scoped>
.component-fade-enter-active,
.component-fade-leave-active {
      
      
  transition: opacity 2s ease;
}
.component-fade-enter,
.component-fade-leave-to {
      
      
  opacity: 0;
}
</style>

7.8 How to animate the for loop (list entry/exit transition)

<template>
  <div id="list-demo" class="demo">
    <button v-on:click="add">Add</button>
    <button v-on:click="remove">Remove</button>
    <transition-group name="list" tag="p">
      <span v-for="item in items" :key="item" class="list-item">
        {
   
   { item }}
      </span>
    </transition-group>
  </div>
</template>

<script>
export default {
      
      
  name: "TransitionTest",
  data() {
      
      
    return {
      
      
      items: [1, 2, 3, 4, 5, 6, 7, 8, 9],
      nextNum: 10,
    };
  },
  methods: {
      
      
    randomIndex: function () {
      
      
      return Math.floor(Math.random() * this.items.length);
    },
    add: function () {
      
      
      this.items.splice(this.randomIndex(), 0, this.nextNum++);
    },
    remove: function () {
      
      
      this.items.splice(this.randomIndex(), 1);
    },
  },
};
</script>
<style scoped>
.list-item {
      
      
  display: inline-block;
  margin-right: 10px;
}
.list-enter-active,
.list-leave-active {
      
      
  transition: all 1s;
}
.list-enter, .list-leave-to {
      
      
  opacity: 0;
  transform: translateY(30px);
}
</style>

reference

Guess you like

Origin blog.csdn.net/letianxf/article/details/129030335