Vue Transition

cause

Due to requirements, it is required to add shopping cart, There was a ball that went from clicking on the add button to getting to the shopping cart. Because I needed to get a dynamic position, I was too busy rendering animations with CSS. Fortunately, vuE-Transition’s built-in component provides JAVASCRIPT hook functions that allow me to complete my animations

practice

First, let’s look at some of the features of the Vue Transition:

Props: name-string, used to automatically generate the CSS transition class name. For example: name:'fade'Fade -enter, fade-enter-active, etc. Default class name"v"Appear - Boolean, whether to use transitions during initial rendering. The default isfalse. Css-boolean, whether to use CSS transition classes. The default istrue. If set tofalse, will trigger registered JavaScript hooks only through component events. Type-string specifies the transition event type and listens for when the transition ends. Valid values for"transition""animation". By default, vue.js will automatically detect long duration transient event types. Mode-string: controls the exit/entry transition time series. There are effective patterns"out-in""in-out"; By default, it takes effect simultaneously. duration - number | {enter: number, leave: number} Specifies the duration of the transition. By default, Vue waits for the first transitionEnd or AnimationEnd event of the root element where the transition is. enter-class - string
    leave-class - string
    appear-class - string
    enter-to-class - string
    leave-to-class - string
    appear-to-class - string
    enter-active-class - string
    leave-active-class - string
    appear-active-class - stringEvents:before-enter
    before-leave
    before-appear
    enter
    leave
    appear
    after-enter
    after-leave
    after-appear
    enter-cancelled
    leave-cancelled (v-show only)
    appear-cancelled
Copy the code

Some specific methods of use, because the content of this article is not very close to the edge, here do not elaborate on the rest will not say here, start the theme

Let me give you an example to illustrate the problem

I don’t know if you have encountered such a problem when writing native JS

When a DOM element changes from display: None to display: block, and you want it to animate like vue transition, you might write something like this

    <div class="c-transition__container" style="display: none;"></div>
Copy the code
    .c-transition__container {
        width: 100px;
        height: 100px;
        background: red;
        transition-duration:.5s;
        transition-property: transform;
    }
Copy the code
    const oDiv = document.getElementsByClassName('c-transition__container') [0]
    document.onclick = function() {
        oDiv.style.transform = 'translate3d(100px, 0, 0)'
        oDiv.style.display = 'block'
    }
Copy the code

The truth is always hard to accept, this will not have a smooth transition effect, but directly in the final position

Frustrated, you quit and vow never to touch it again:

Don't worry, how do YOU smooth from zero to one

First we need to understand the browser’s rendering timing

    for(let i = 0; i < 100; i++) {
        oDiv.style.transform = 'translate(100px, 0, 0)'
    }
Copy the code

The for loop above manipulates the div 100 times, but the browser doesn’t actually render it 100 times

You misunderstood Vue nextTick

As we can see, the browser UI Render is triggered only once after each macroTask has finally emptied the microTask queue, but the browser determines whether to Render according to the actual situation and usually renders once every 16.7ms, during which time, The browser pushes all DOM operations into the queue and pulls them out one by one during rendering until the queue is empty.

Browser rendering process:

JavaScript: JavaScript implements animation effects, DOM element manipulation, etc. (Cpu) Style: Determine what CSS rules should be applied to each DOM element. (Cpu) Layout: Calculates the size and position of each DOM element on the final screen. Since the layout of elements on a Web page is relative, changes in the position of any element will cause changes in other elements. This process is called reflow. Paint: Draw text, colors, images, borders, and shadows of DOM elements on multiple layers. This process is called repaint. (Cpu) Composite: Combine layers in a reasonable order and display them on the screen. (Go to GPU) (Render Tree parse render)Copy the code

With that in mind, the next question is easy to solve

Let’s analyze the case sentence by sentence:

  1. First we initialize some basic div states, including width, height, transition, and some CSS styles
  2. When we click on Document, we copy the div style totranslate(100px, 0, 0)“And updated the statusdisplay: blockNotice that at this point, the browser that I was talking about, it’s not rendering directly, it’s pushing it into a queue, but remember, the DOM Tree is updating in real time, so it’s not rendering, but it’s updating the state in the DOM Tree, At this point, the DOM Transform has changed to 100px, and when it actually renders, it changes from 100px to 100px, not from 0 to 100px, so we see no transitions.

The solution

From the above analysis, we can basically understand why this phenomenon occurs. Here are the solutions:

  1. The first is the well-known setTimeout, which can indeed solve the above problems, but setTimeout belongs to macroTask, each task will trigger a UI Render at the end, the above operation will cause multiple renders, so it is not recommended to use

  2. (Recommended) Force the browser to clear the queue for rendering

    When retrieving layout information, it forces the browser to clear the queue for rendering. There are several apis: innerHeight, scrollTop, offsetHeight, getBoundingClientRect, and so on

    At this time, the browser re-backflow redraw rendering operation, this time trigger DOM operation can be effectively feedback

conclusion

The Vue transitionJS hook function is an animation written by native JS, and also smoothen from scratch.