This is the second day of my participation in the August More Text Challenge


series

  • Vue 3 basis
  • Vue 3 dynamic effect
  • Vue 3 components
  • Modular API
  • Vue Router Next
  • Vuex 4

This paper introduces the transition dynamic effects of Vue 3 elements entering (display)/leaving (hide) and list (rearrange), mainly aiming at the differences between 🎉 and Vue 2.

The transition dynamic effects supported by Vue are mainly implemented based on transition and animation properties of CSS3 for elements entering (showing)/leaving (hiding) and list (rearranging).

💡 For other transitional effects and performance considerations for creating smooth animations on the Web, see the official article chapter.

Common cases of triggering animation in Vue:

  • Conditions apply colours to a drawingv-if 或 v-showToggle, dynamic component propertiesisswitch
  • List update
  • Status updates

Elements enter/leave transitions

Vue provides a built-in component
as a container, and then there are several ways to animate the (immediate child) elements wrapped within it:

  • Automatically adds a specific to the element where the transition occursclass(and remove the corresponding one after the endclassProperties) can be based on theseclassProperties are animated using CSS. And you can customize itclassProperty values for easy integration with third-party CSS animation libraries, such asanimate.css
  • When the transition occurs, the corresponding transition hook function is triggered, which is convenient to realize the animation through JS, and the third-party JavaScript animation library can also be integrated

CSS transition

Vue inserts six class attributes with different suffixes for elements at different stages of transition. You can use these classes as selectors to more finely style elements at different stages of transition:

  • 🎉 v-enter-fromDefine the beginning state of the transition, which takes effect before the element is inserted, and is removed the next frame after the element is inserted.
  • v-enter-activeApply throughout the transition phase and remove after the transition/animation is complete. You can use this class name as a CSS selector to set transition effects, for example by setting CSS propertiestransitionDefine the process time, delay, or curve function that enters the transition.
  • v-enter-toDefine the end state of the transition. The next frame takes effect after the element is inserted (at the same timev-enter-fromRemoved) after the transition/animation is complete.
  • 🎉 v-leave-fromDefine the beginning state of the exit transitionImmediately after the exit transition is triggered, the next frame is removed.
  • v-leave-activeApply throughout the exit transition phase and remove after the transition/animation is complete. You can use this class name as a CSS selector to set transition effects, for example by setting CSS propertiestransitionDefine exit transition process time, delay, and curve function.
  • v-leave-to: Leaving the end state of transition. The next frame takes effect after the exit transition is triggered (at the same timev-leave-fromRemoved) after the transition/animation is complete.

💡 Each of the six different class attributes uses v- as the default prefix. If the container tag has the attribute name
, The dynamically inserted class attribute name is prefixed with animationType-, i.e., v-Enter is replaced with animationType- Enter. Remember to style with the appropriate prefix, not the default prefix V -.

<div id="demo">
  <button @click="show = ! show">
    Toggle show
  </button>

  <transition name="slide-fade">
    <p v-if="show">hello</p>
  </transition>
</div>
Copy the code
const Demo = {
  data() {
    return {
      show: true
    }
  }
}

Vue.createApp(Demo).mount('#demo')
Copy the code
/* You can set different entry and exit animations */
/* Sets the duration and animation function */
.slide-fade-enter-active {
  transition: all 0.3 s ease-out;
}

.slide-fade-leave-active {
  transition: all 0.8 s cubic-bezier(1.0.5.0.8.1);
}

.slide-fade-enter-from..slide-fade-leave-to {
  transform: translateX(20px);
  opacity: 0;
}
Copy the code

If you want to use third-party CSS libraries such as Animate. CSS, you generally need to insert specific class names on DOM elements to apply the corresponding CSS styles. You can use attributes listed below on the
tag. Vue then adds the corresponding custom transition class name to the changed (immediate child) element in the container at the corresponding stage of the transition:

  • 🎉 enter-from-class="custom-class-name"The class name added to the element before it enters the page
  • enter-active-class="custom-class-name"
  • enter-to-class="custom-class-name"
  • 🎉 leave-from-class="custom-class-name"
  • leave-active-class="custom-class-name"
  • leave-to-class="custom-class-name"
<link
  href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.0/animate.min.css"
  rel="stylesheet"
  type="text/css"
/>

<div id="demo">
  <button @click="show = ! show">
    Toggle render
  </button>

  <transition
    name="custom-classes-transition"
    enter-active-class="animate__animated animate__tada"
    leave-active-class="animate__animated animate__bounceOutRight"
  >
    <p v-if="show">hello</p>
  </transition>
</div>
Copy the code
const Demo = {
  data() {
    return {
      show: true
    }
  }
}

Vue.createApp(Demo).mount('#demo')
Copy the code

💡 If the animation property is used to achieve dynamic effects instead of transition control, there is no need to specify the state of V-enter-from/V-leave-from or V-Enter-to-V-leave-to. Just set the CSS property animation in the V-Enter-active/V-leave-active transition, where the styles of 0% and 100% states specified in the keyframe are the start and end states

<div id="demo">
  <button @click="show = ! show">
    Toggle show
  </button>
  <transition name="bounce">
    <p v-if="show">hello</p>
  </transition>
</div>
Copy the code
const Demo = {
  data() {
    return {
      show: true
    }
  }
}

Vue.createApp(Demo).mount('#demo')
Copy the code
.bounce-enter-active {
  animation: bounce-in 0.5 s;
}
.bounce-leave-active {
  animation: bounce-in 0.5 s reverse;
}
@keyframes bounce-in {
  0% {
    transform: scale(0);
  }
  50% {
    transform: scale(1.25);
  }
  100% {
    transform: scale(1); }}Copy the code

💡 Vue can automatically determine the completion time of the transition effect by “unplugging” the associated class name added to the element. However, if (not recommended) you use the CSS properties Trasition and animation to set the animation, the transition time may be different. For example, the animation is triggered and finished very quickly, and the transition is not finished, and there are some unexpected animation bugs. Add the type option to the container and set it to animation or Transition to explicitly declare the type of transition animation that you want Vue to listen to. You can also explicitly specify the duration (in milliseconds) on the container element via prop
.

💡 Dynamic effect If it does not work when the page is first loaded, you can set the transition of the node’s initial rendering by adding the “Appear” attribute to the element
.

Hook function

Vue fires events at different stages of the transition at the same time. You can listen for these events in the built-in component
, and then control the animation “manually” in the event handler using JS, usually by setting attribute styles for elements, or by “hooking” to other animation frameworks, such as GSAP:

<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"
>
  <! -... -->
</transition>
Copy the code
// ...
methods: {
  The /* * element enters */
  beforeEnter(el) {
    // ...
  },
  // When combined with CSS
  The done callback is optional
  enter(el, done) {
    // ...
    done()
  },
  afterEnter(el) {
    // ...
  },
  enterCancelled(el) {
    // ...
  },

  /* * the element leaves */
  beforeLeave(el) {
    // ...
  },
  // When combined with CSS
  The done callback is optional
  leave(el, done) {
    // ...
    done()
  },
  afterLeave(el) {
    // ...
  },
  // leaveCancelled is used only in V-show
  leaveCancelled(el) {
    // ...}}Copy the code
  • @before-enter="beforeEnter(el)"You can pass elements that perform animations
  • @enter="enter(el, done)"In the callback function,Called when the animation execution completesdone()Tell Vue that the animation is over, must be executed oncedone()Otherwise, they will be called synchronously and the transition will complete immediately.
  • @after-enter="afterEnter"
  • @enter-cancelled="enterCancelled"The event triggered when the element leaves the page
  • @before-leave="beforeLeave"
  • @leave="leave"In the callback function,Called when the animation execution completesdone()Tell Vue that the animation is over, must be executed oncedone()Otherwise, they will be called synchronously and the transition will complete immediately.
  • @after-leave="afterLeave"
  • @leave-cancelled="leaveCancelled"

💡 Although these hook functions can be used in conjunction with CSS Transitions /animations, they can also be used alone. If you only use JS transitions, it is recommended to add the V-bind: CSS =”false” attribute to
. Vue skips CSS detection and avoids CSS effects during transitions.

Transitions between multiple elements

In multi-element transitions, the default mode is for two elements to enter and leave at the same time, which may cause the layout to mess up. You can change the transition mode to
so that the current element leaves first and the new element enters after it is finished.

<transition name="fade" mode="out-in">
  <! -... the buttons ... -->
</transition>
Copy the code

💡 For switching between multiple elements using V-if/V-else, 🎉 Vue 3 automatically generates unique keys for each branch item of V-IF/V-else/V-else if by default, so the key attribute of these elements is no longer necessary. If you need to set a unique value when adding the key attribute, switching between elements with the same label name will only replace the internal content instead of triggering the entire element switching transition.

List rearrangement transition

Use the component
as a container, which can have multiple nodes (
allows only one root node, although multiple elements can be wrapped, but after each V-if or V-show switch, Only one root node can be rendered), remember that each node within it always needs to be uniquely identified by the attribute key.

<transition-group name="list" tag="p">
  <span v-for="item in items" :key="item" class="list-item">
    {{ item }}
  </span>
</transition-group>
Copy the code

Vue also inserts the six different suffix classes described above for elements at different stages of the transition, and you can use these classes as selectors to set styles.

  • 🎉 v-enter-from
  • v-enter-active
  • v-enter-to
  • 🎉 v-leave-from
  • v-leave-active
  • v-leave-to

Animationtype-move (animationType-move); animationType-move (animationType-move); animationType-move (animationType-move); You can also set the class name manually using move-class attribute as before. Typically, the V-move selector is used to set the CSS property Transform to specify transition timing and easing curves, and then Vue will smoothly transition the element from its previous position to the new position, creating an animation called FLIP.

<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script>

<div id="flip-list-demo">
  <button @click="shuffle">Shuffle</button>
  <transition-group name="flip-list" tag="ul">
    <li v-for="item in items" :key="item">
      {{ item }}
    </li>
  </transition-group>
</div>
Copy the code
const Demo = {
  data() {
    return {
      items: [1.2.3.4.5.6.7.8.9]}},methods: {
    shuffle() {
      // Rearrange the list elements using Lodash shuffle
      this.items = _.shuffle(this.items)
    }
  }
}

Vue.createApp(Demo).mount('#flip-list-demo')
Copy the code
.flip-list-move {
  transition: transform 0.8 s ease;
}
Copy the code

💡 🎉 In Vue 3,
does not render the root node by default, but can be set with the attribute tag, for example tag=”div” will use the

element as a container-wrapped list.

💡 FLIP dynamic effect is invalid for display: inline elements, but can be set to display: inline-block for inline elements, such as

Dynamic transition

You can manipulate the transitionName type in real time by binding the attribute name to a variable, since the event hook is a method. They can access data in any context, which means transitions can behave differently depending on the state of the component, such as switching directions and transitions when clicking the left and right arrows on a wheel map.

State transition

Transition effects can also be set for changes to the element’s content/data itself, including numbers and operations, color display, position of SVG nodes, element size, and other properties.

In general, style attributes expressed in numerical values can be set dynamic effects, and third-party libraries can be combined with Vue’s responsive and component systems to realize the transition state of switching elements, such as tween.js and GSAP