An overview of the
Vue provides a variety of different application transitions when inserting, updating, or removing the DOM. Includes the following tools:
- Automatically applies to CSS transitions and animations
class
- Can be used in conjunction with third-party CSS animation libraries such as
Animate.css
- Use JavaScript to manipulate the DOM directly in transitional hook functions
- Can be used in conjunction with third-party JavaScript animation libraries such as
Velocity.js
In addition to these useful apis, it is worth mentioning that class and style declarations can also be applied to animations and transitions for simpler use cases.
Vue Animation Mode 1-CSS Transition
Vue provides a wrapper component for Transition, and you can add an entry/exit transition to any element or component in the following cases
- Conditional rendering (use
v-if
) - Conditional display (use
v-show
) - Dynamic components
- Component root node
Here’s a typical example:
//HTML <div id="demo"> <button v-on:click="visible = ! visible"> Toggle </button> <transition name="fade"> <p v-if="visible">hello</p> </transition> </div>Copy the code
//JS
new Vue({
el: '#demo',
data: {
visible: true
}
})
Copy the code
//CSS .fade-enter-active, .fade-leave-active { transition: opacity .5s; Fade-enter,.fade-leave-to /*. Fade-leave-active below version 2.1.8 */ {opacity: 0; }Copy the code
When inserting or deleting elements contained in the Transition component, Vue does the following:
Automatically sniff out if the target element has CSS transitions or animations applied, and if so, add/remove CSS class names when appropriate.
If the transition component provides JavaScript hook functions, these hook functions will be called at the appropriate time.
If the JavaScript hook is not found and CSS transitions/animations are not detected, the DOM operation (insert/delete) is performed immediately in the next frame. (Note: this refers to the frame-by-frame animation mechanism of the browser, unlike Vue’s nextTick concept.)
The class name of the transition
There are six class switches in the entry/exit transition.
-
V-enter: defines the start state of the transition. It takes effect before the element is inserted and is removed the next frame after the element is inserted. (Frame 1)
-
V-enter -active: defines the status when the transition takes effect. Applied throughout the transition phase, before the element is inserted and removed after the transition/animation is complete. This class can be used to define the process time, delay, and curve functions that enter the transition.
-
V-enter -to: indicates the end state of the transition defined in version 2.1.8 or later. The next frame takes effect after the element is inserted (the V-enter is removed at the same time) and removed after the transition/animation is complete.
-
V-leave: Defines the start state of the exit transition. Immediately after the exit transition is triggered, the next frame is removed.
-
V-leave-active: defines the status when the leave transition takes effect. Applies throughout the exit transition phase, takes effect immediately when the exit transition is triggered, and removes after the transition/animation is complete. This class can be used to define exit transition process time, delay and curve functions.
-
V-leave-to: the end state of the departure transition defined in version 2.1.8 and above. The next frame takes effect after the exit transition is triggered (and the V-leave is deleted at the same time), and is removed after the transition/animation is complete.
V – is the default prefix for class names that are switched in transition if you use a
V-enter-active and V-leave-active control different mitigation curves for the entry/exit transition.
Common transitions are CSS transitions.
Here’s a simple example:
//HTML <div id="example-1"> <button @click="show = ! show"> Toggle render </button> <transition name="slide-fade"> <p v-if="show">hello</p> </transition> </div>Copy the code
//JS
new Vue({
el: '#example-1',
data: {
show: true
}
})
Copy the code
//CSS /* You can set different entry and exit animations */ /* You can set duration and animation functions */. Slide-fade -enter-active {transition: all.3s ease; }. Slide-fade-leave-active {transition: all.8s cubic- Bezier (1.0, 0.5, 0.8, 1.0); }.slide-fade-enter,.slide-fade-leave-to /*.slide-fade-leave-active for below version 2.1.8 */ {transform: translateX(10px); opacity: 0; }Copy the code
Vue animation 2-CSS Animation
CSS animations are used in the same way as CSS, except that the v-Enter class name is not deleted immediately after the DOM is inserted, but when the AnimationEnd event is triggered.
Example :(compatibility prefix omitted)
//HTML <div id="example-2"> <button @click="show = ! show">Toggle show</button> <transition name="bounce"> <p v-if="show">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris facilisis enim libero, at lacinia diam fermentum id. Pellentesque habitant morbi tristique senectus et netus.</p> </transition> </div>Copy the code
//JS
new Vue({
el: '#example-2',
data: {
show: true
}
})
Copy the code
//CSS .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); }}Copy the code
Custom transition class name
We can customize the transition class name using the following attributes:
- enter-class
- enter-active-class
- Enter – to – class (2.1.8 +)
- leave-class
- leave-active-class
- Leave – to – class (2.1.8 +)
They take precedence over normal class names, which is useful when used in conjunction with Vue’s transition system and other third-party CSS animation libraries such as animation.css.
Example:
/ / HTML < link href = "https://cdn.jsdelivr.net/npm/[email protected]" rel = "stylesheet" type = "text/CSS" > < div id="example-3"> <button @click="show = ! show"> Toggle render </button> <transition name="custom-classes-transition" enter-active-class="animated tada" leave-active-class="animated bounceOutRight" > <p v-if="show">hello</p> </transition> </div>Copy the code
//JS
new Vue({
el: '#example-3',
data: {
show: true
}
})
Copy the code
Use both transitions and animations
In order for Vue to know that the transition is complete, it must set up the appropriate event listener. It can be transitionEnd or AnimationEnd, depending on the CSS rules applied to the element. If you use any of these, Vue automatically recognizes the type and sets up a listener.
However, in some scenarios, you may need to have two transition effects for the same element at the same time. For example, the animation is triggered quickly and completed, and the transition effect is not finished. In this case, you need to use the Type attribute and set the animation or transition to explicitly declare the type you want Vue to listen to.
The duration of the apparent transition
2.2.0 new
In many cases, Vue can automatically determine when the transition effect is completed. By default, Vue waits for its first transitionEnd or AnimationEnd event at the root of the transition effect. However, this could not be the case — for example, we could have a well-choreographed series of transitions in which some nested inner elements have delayed or longer transitions than the root element of the transition.
In this case you can customize an explicit transition duration (in milliseconds) using duration Prop on the < Transition > component:
<transition :duration="1000">... </transition>Copy the code
You can also customize the duration of entry and removal:
<transition :duration="{ enter: 500, leave: 800 }">... </transition>Copy the code
Vue animation mode 3-JS animation operation
You can declare JavaScript hooks in attributes
//HTML <transition v-on:before-enter="beforeEnter" v-on:enter="enter" v-on:after-enter="afterEnter" v-on:enter-cancelled="enterCancelled" v-on:before-leave="beforeLeave" v-on:leave="leave" v-on:after-leave="afterLeave" v-on:leave-cancelled="leaveCancelled" > <! -... --> </transition>Copy the code
//JS // ... Methods: {/ / -- -- -- -- -- -- -- -- / / into / / -- -- -- -- -- -- -- -- beforeEnter: function (el) {/ /... }, // When used with CSS // the callback done function is optional Enter: function (el, done) {//... done() }, afterEnter: function (el) { // ... }, enterCancelled: function (el) { // ... }, / / -- -- -- -- -- -- -- -- / / / / when they leave -- -- -- -- -- -- -- -- beforeLeave: function (el) {/ /... }, // When used with CSS // leave: function (el, done) {//... done() }, afterLeave: function (el) { // ... }, // the cat will take the data out of the cat for v-show. }}Copy the code
These hook functions can be used in conjunction with CSS Transitions /animations or separately.
When transitioning only with JavaScript, you must use done for callbacks in enter and leave. Otherwise, they will be called synchronously and the transition will complete immediately.
It is recommended to add V-bind: CSS =”false” for elements that use JavaScript transitions only. Vue skips CSS detection. This also avoids the impact of CSS during the transition.
A simple example using velocity.js:
Velocity works in a similar way to jquery.animate and is a great choice for implementing JavaScript animations
/ / HTML < script SRC = "https://cdnjs.cloudflare.com/ajax/libs/velocity/1.2.3/velocity.min.js" > < / script > < div id="example-4"> <button @click="show = ! show"> Toggle </button> <transition v-on:before-enter="beforeEnter" v-on:enter="enter" v-on:leave="leave" v-bind:css="false" > <p v-if="show"> Demo </p> </transition> </div>Copy the code
//JS new Vue({ el: '#example-4', data: { show: false }, methods: { beforeEnter: function (el) { el.style.opacity = 0 el.style.transformOrigin = 'left' }, enter: Function (el, done) {Velocity(el, {opacity: 1, fontSize: '1.4em'}, {duration: 300}) Velocity(el, {fontSize: '1em' }, { complete: done }) }, leave: function (el, done) { Velocity(el, { translateX: '15px', rotateZ: '50deg' }, { duration: 600 }) Velocity(el, { rotateZ: '100deg' }, { loop: 2 }) Velocity(el, { rotateZ: '45deg', translateY: '30px', translateX: '30px', opacity: 0 }, { complete: done }) } } })Copy the code
conclusion
Hook + velocity. Js + done ()
Vue animation mode 4- Multi-element animation
We’ll discuss transitions to multiple components later, using V-if/V-else for native tags. The most common multi-tag transitions are a list and elements that describe the list as empty messages:
<transition> <table v-if="items.length > 0"> <! -... --> </table> <p v-else>Sorry, no items found.</p> </transition>Copy the code
It can be used this way, but with one caveat:
When elements with the same tag name are switched, a unique value must be set through the key attribute so that Vue can distinguish between them. Otherwise, Vue will only replace the contents of the same tag for efficiency. Even if it is not technically necessary, it is a better practice to set keys for multiple elements in the < Transition > component.
Example (always add key) :
<transition>
<button v-if="isEditing" key="save">
Save
</button>
<button v-else key="edit">
Edit
</button>
</transition>
Copy the code
In some scenarios, it is also possible to replace V-if and V-else by setting different states for the key attribute of the same element. The above example can be rewritten as:
<transition>
<button v-bind:key="isEditing">
{{ isEditing ? 'Save' : 'Edit' }}
</button>
</transition>
Copy the code
A transition of multiple elements using multiple V-Ifs can be rewritten as a transition of a single element with a dynamic property bound. Such as:
<transition>
<button v-if="docState === 'saved'" key="saved">
Edit
</button>
<button v-if="docState === 'edited'" key="edited">
Save
</button>
<button v-if="docState === 'editing'" key="editing">
Cancel
</button>
</transition>
Copy the code
Can be rewritten as:
<transition>
<button v-bind:key="docState">
{{ buttonMessage }}
</button>
</transition>
// ...
computed: {
buttonMessage: function () {
switch (this.docState) {
case 'saved': return 'Edit'
case 'edited': return 'Save'
case 'editing': return 'Cancel'
}
}
}
Copy the code
The default behavior of
A simultaneous entry and exit transition does not satisfy all requirements, so Vue provides a transition mode
-
In-out: The new element transitions first, and then the current element transitions away.
-
Out-in: The current element transitions first, and then the new element transitions in.
Rewrite the previous switch button transition with out-of-in:
<transition name="fade" mode="out-in"> <! -... the buttons ... --> </transition>Copy the code
Adding a simple attribute solves the previous transition problem without any additional code.
In-out mode is not used very often, but is useful for slightly different transitions.
Transitions of multiple components
Transitioning from multiple components is much easier – we don’t need to use key attributes. Instead, we just need to use dynamic components:
//html
<button @click="view=v-a">A</button>
<button @click="view=v-b">B</button>
<transition name="component-fade" mode="out-in">
<component v-bind:is="view"></component>
</transition>
Copy the code
//js
new Vue({
el: '#transition-components-demo',
data: {
view: 'v-a'
},
components: {
'v-a': {
template: '<div>Component A</div>'
},
'v-b': {
template: '<div>Component B</div>'
}
}
})
Copy the code
//css .component-fade-enter-active, .component-fade-leave-active { transition: opacity .3s ease; }.component-fade-enter,.component-fade-leave-to /*. Component-fade -leave-active for below version 2.1.8 */ {opacity: 0; }Copy the code
conclusion
button key = 'xxx' + mode = out-in/in-out
<component :is='xxx'></component> + xxx = v-a/v-b/v-c
Vue animation mode 5- List animation
So far, we’ve talked about the transition:
- A single node
- Render one of multiple nodes at the same time
So how do you render the entire list at the same time, say using V-for? In this scenario, the
- Different from the
<transition>
, it will be rendered as a real element: the default is one<span>
. You can also passtag
Attribute is replaced with another element. - In-out /out-in mode is not available because we no longer switch unique elements between each other.
- Internal elements always need to provide unique
key
The attribute value. - CSS transitioning classes will be applied to internal elements, not the group/container itself.
List entry/exit transitions
Now let’s dive in with a simple example, entering and leaving the transition using the same CSS class name as before.
//HTML <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" v-bind:key="item" class="list-item"> {{ item }} </span> </transition-group> </div>Copy the code
//JS new Vue({el: '#list-demo', data: {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) }, } })Copy the code
//CSS .list-item { display: inline-block; margin-right: 10px; } .list-enter-active, .list-leave-active { transition: all 1s; }.list-enter,.list-leave-to /*. List-leave-active for below version 2.1.8 */ {opacity: 0; transform: translateY(30px); }Copy the code