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:
- First we initialize some basic div states, including width, height, transition, and some CSS styles
- When we click on Document, we copy the div style to
translate(100px, 0, 0)
“And updated the statusdisplay: block
Notice 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:
-
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
-
(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.