Adding a few transitions or animations to a cold web page can dramatically improve the texture of the page, giving it a smooth, silky look. It is implemented mainly through the TRANSITION and animation in CSS.
It is encapsulated in VUE framework to provide convenient transition usage.
1, Transition component usage
The transition component is most commonly used in business development:
<transition name="slide-fade">
<p v-if="show"> hello world </p>
</transition>
Copy the code
/* You can set different entry and exit animations */
/* Sets the duration and animation function */
.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
transform: translateX(10px);
opacity: 0;
}
Copy the code
In the entry/exit transition, six hooks are triggered and six class switches are performed.
If your Transition component does not have a name attribute, v- is the default prefix for these class names. If you use
These six class names are customizable and take precedence over normal class names:
<transition name="slide-fade"
enter-active-class="custom-enter-active-class"
leave-active-class="custom-leave-active-class">
<p v-if="show"> hello world </p>
</transition>
Copy the code
/* CSS section */
.custom-enter-active-class {
animation: bounce-in .5s;
}
.custom-leave-active-class {
animation: bounce-in .5s reverse;
}
@keyframes bounce-in {
0% {
transform: scale(0);
}
50% {
transform: scale(1.5);
}
100% {
transform: scale(1); }}Copy the code
When switching between elements with the same tag name, it is recommended to set keys for multiple elements in the < Transition > component so that vUE can distinguish between them
<transition> <button v-if="isEditing" key="save"> Save </button> <button v-else key="edit"> Edit </button> </transition> Copy the code
This example can replace v-if with different values for key:
<transition> <button :key="isEditing"> {{ isEditing ? 'Save' : 'Edit' }} </button> </transition> Copy the code
Also switch transitions between different components:
<transition name="component-fade" mode="out-in">
<component :is="view"></component>
</transition>
Copy the code
export default {
data () {
return {
view: 'v-a'}},components: {
'v-a': {
template: '<div>Component A</div>'
},
'v-b': {
template: '<div>Component B</div>'}}}Copy the code
By default, these two components is enter and leave at the same time, a left transition began to shift into another, only to leave the components of the completion of animation, will only let the position, which can cause a caton usually effect (if two elements are set up absolute positioning, there is no this problem).
We can satisfy our needs by adding the transition mode mode:
in-out
: The new element transitions first, then the current element transitions away.out-in
: The current element transitions first, and then the new element transitions in.
In general, we use out-of-in more often, allowing the current element to leave before new elements enter.
<transition name="fade" mode="out-in">
<! -- Different elements -->
</transition>
Copy the code
Knowing the above usage, you are ready to implement most business scenarios.
2. Use JavaScript for dynamic transitions
For most scenarios, we use CSS primarily for transitions, which are already written up front, but in some cases we also need dynamic transitions.
The most basic operation of dynamic transition is to bind dynamic attributes, such as name, and switch different transition effects in different situations.
<transition :name="transitionName">
<! -... -->
</transition>
Copy the code
However, this also requires us to write the corresponding transition effect in advance. Besides, the most direct way to achieve dynamic transition is to use JavaScript transition:
<transition
@before-enter="beforeEnter"
@enter="enter"
@after-enter="afterEnter"
@enter-cancelled="enterCancelled"
@before-leave="beforeLeave"
@leave="leave"
@after-leave="afterLeave"
@leave-cancelled="leaveCancelled"
>
<! -... -->
</transition>
Copy the code
methods: {
// The transition is triggered before entering
beforeEnter: function (el) {},// Triggered when transition enters
enter: function (el, done) {
// ...
The done callback is optional when used with CSS
If CSS ="false", the done callback must be used
done()
},
// Triggered when the transition enters the end
afterEnter: function (el) {},// Triggered when transition entry is cancelled
enterCancelled: function (el) {},// Trigger before leaving
beforeLeave: function (el) {},// Triggered when leaving
leave: function (el, done) {
// ...
When used with CSS, the done callback is optional
If CSS ="false", the done callback must be used
done()
},
// Triggers after leaving
afterLeave: function (el) {},// Triggered when the exit process is cancelled (only used in V-show)
leaveCancelled: function (el) {}}Copy the code
The JavaScript transitions hooks above can be used with CSS Transitions /animations or separately.
However, since you are using JavaScript transitions, it is recommended not to use CSS transitions. Add v-bind: CSS =”false” to the element and Vue will skip the CSS detection. This also avoids the impact of CSS during the transition.
Take this example:
<! -- Velocity works in a similar way to jquery.animate and is a great choice for implementing JavaScript animations.
<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
@before-enter="beforeEnter"
@enter="enter"
@leave="leave"
:css="false"
>
<p v-if="show">
Demo
</p>
</transition>
</div>
Copy the code
new Vue({
el: '#example-4'.data: {
show: false
},
methods: {
// Write specific transition data in the hook function, can realize JS dynamic control
beforeEnter: function (el) {
el.style.opacity = 0
el.style.transformOrigin = 'left'
},
enter: function (el, done) {
Velocity(el, { opacity: 1.fontSize: '1.4 em' }, { 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
3, initial render appear
The use of transitions above usually requires changes in elements or components, such as V-if, V-show, dynamic components, etc.
You can use the “Appear” attribute if your request is rendered the first time it comes to the page, and then doesn’t need to be rendered again. Here’s an example:
<! -- Appear can also customize the CSS class name -->
<transition appear
appear-class="custom-appear-class"
appear-active-class="custom-appear-active-class"
appear-to-class="custom-appear-to-class">
<p>I'm a test appear initial render text</p>
</transition>
Copy the code
.custom-appear-class{
opacity: 0;
}
.custom-appear-active-class{
transition: all 3s;
}
.custom-appear-to-class{
opacity: 1;
}
Copy the code
“Appear” is a bit like “Enter”, but it only fires during the initial rendering, and you can make a natural transition by setting the state before and after it fires differently.
It can also be implemented using JavaScript hook functions:
<transition appear
@before-appear="customBeforeAppearHook"
@appear="customAppearHook"
@after-appear="customAfterAppearHook"
@appear-cancelled="customAppearCancelledHook">
<! -... -->
</transition>
Copy the code
4. List transitions and V-moves
Use the
- Different from the
<transition>
, it will be rendered as a real element: the default is one<span>
. Can be achieved bytag
Property is replaced with another element. - There is no transition mode in the list rendering.
- Internal elements must be provided
key
Value.
<! -- Set the tag attribute to p element, and set the key value for each item in v-for -->
<! -- items is an array of consecutive numbers [0, 1, 2...] -->
<transition-group name="list" tag="p" class="list-item">
<span v-for="item in items" :key="item">
{{ item }}
</span>
</transition-group>
Copy the code
.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);
}
Copy the code
It looks like this, but there’s a problem: as you add and remove elements, the surrounding elements will teleport to their new layout position, giving the impression of being stuck.
You can solve this problem by using the V-move class in the
So just modify the CSS in the above example:
.list-item {
display: inline-block;
margin-right: 10px;
}
/* Add a.list-move class style, which takes effect when the element changes */
.list-move{
transition: all 1s;
}
.list-enter-active..list-leave-active {
transition: all 1s;
}
/* Add an absolute positioning attribute */ when the element leaves
/* When the element leaves, it triggers a position change to make the above.list-move effective */
/* If there is no absolute positioning, the element will leave the action and the surrounding elements will move to its position */
/* By that time all transitions have been completed. List-move has been removed, causing a lag */
.list-leave-active {
position: absolute;
}
.list-enter..list-leave-to {
opacity: 0;
transform: translateY(30px);
}
Copy the code
This gives it a silky feel, and the CSS above can be further simplified:
/* Add transition directly to the element */
/* It applies to all elements that change, including v-move */
.list-item {
display: inline-block;
margin-right: 10px;
transition: all 1s;
}
/* So v-move and V-active are not needed */
/* Just add an absolute positioning attribute when the element leaves */
.list-leave-active {
position: absolute;
}
.list-enter..list-leave-to {
opacity: 0;
transform: translateY(30px);
}
Copy the code
Note: The internal implementation of V-Move, Vue, uses a simple animation queue called FLIP.
Elements that use FLIP transitions cannot be set to
display: inline
。So I can set it to
display: inline-block
Or put it in Flex.