过度动画
类名
- v-enter-from:进入动画的起始状态。
- v-enter-active:进入动画的生效状态。
- v-enter-to:进入动画的结束状态。
- v-leave-from:离开动画的起始状态。
- v-leave-active:离开动画的生效状态。
- v-leave-to:离开动画的结束状态。
class命名规则
我们可以给 <Transition>
组件传一个 name prop 来声明一个过渡效果名:
js
<Transition name="dsj">
...
</Transition>
对于一个有名字的过渡效果,对它起作用的过渡 class 会以其名字而不是 v 作为前缀。比如,上方例子中被应用的 class 将会是 dsj-enter-active 而不是 v-enter-active。这个“dsj”过渡的 class 应该是这样:
css
.dsj-enter-active {
...
}
CSS 的 transition
js
import { ref } from 'vue'
const isShow = ref(false)
html
<button @click="isShow = !isShow"> 切换 </button>
<hr>
<transition>
<h2 class="" v-if="isShow">不忘初心,方得始终.</h2>
</transition>
css
h2 {
display: inline-block;
}
.v-enter-from,
.v-leave-to {
opacity: 0;
transform: scale(.5);
}
.v-enter-to,
.v-leave-from {
opacity: 1;
transform: scale(1);
}
.v-enter-active,
.v-leave-active {
transition: all 2s ease;
}
CSS 的 animation
js
import { ref } from 'vue'
const isShow = ref(false)
html
<button @click="isShow = !isShow"> 切换 </button>
<hr>
<transition name="dsj">
<h2 class="" v-if="isShow">不忘初心,方得始终.</h2>
</transition>
css
h2 {
display: inline-block;
}
.dsj-enter-active {
animation: dsjEnterAnim 2s ease;
}
.dsj-leave-active {
animation: dsjLeaveAnim 2s ease;
}
@keyframes dsjEnterAnim {
0% {
opacity: 0;
transform: scale(0);
}
50% {
opacity: .5;
transform: scale(.5);
}
100% {
opacity: 1;
transform: scale(1);
}
}
@keyframes dsjLeaveAnim {
0% {
opacity: 1;
transform: scale(1);
}
50% {
opacity: .5;
transform: scale(.5);
}
100% {
opacity: 0;
transform: scale(0);
}
}
过渡模式
在之前的例子中,进入和离开的元素都是在同时开始动画的,因此我们不得不将它们设为 position: absolute 以避免二者同时存在时出现的布局问题。
js
<div>
<button @click="isShow = !isShow">切换</button>
</div>
<transition name="dsj" mode="out-in">
<h2 v-if="isShow">哈哈哈</h2>
<h2 v-else>嘻嘻嘻</h2>
</transition>
mode="out-in" 先移除后加入
mode="in-out" 先加入后移除(少)
动态组件的切换
js
import { ref } from 'vue';
import Home from './pages/Home.vue'
import About from './pages/About.vue'
const isShow = ref(false)
html
<div>
<button @click="isShow = !isShow">切换</button>
</div>
<!-- 首次渲染动画 appear -->
<transition name="dsj" mode="out-in" appear>
<component :is="isShow ? Home:About"></component>
</transition>
列表动画
js
import { ref } from 'vue';
import { shuffle } from 'underscore'
const nums = ref([1, 2, 3, 4, 5, 6, 7, 8, 9])
const addNumber = () => {
nums.value.splice(randomIndex(), 0, nums.value.length)
}
const removeNumber = () => {
nums.value.splice(randomIndex(), 1)
}
const shuffleNumber = () => {
nums.value = shuffle(nums.value)
}
const randomIndex = () => {
return Math.floor(Math.random() * nums.value.length)
}
html
<button @click="addNumber">添加数字</button>
<button @click="removeNumber">删除数字</button>
<button @click="shuffleNumber">打乱数字</button>
<hr>
<transition-group tag="div" name="dsj">
<template v-for="item in nums" :key="item">
<div class="item">{{ item }}</div>
</template>
</transition-group>
css
.item {
display: inline-block;
margin: 10px;
}
.dsj-enter-from,
.dsj-leave-to {
opacity: 0;
transform: translateY(30px);
}
.dsj-enter-to,
.dsj-leave-from {
opacity: 1;
transform: translateY(0);
}
.dsj-enter-active,
.dsj-leave-active {
transition: all 2s ease;
}
/* 移除时不让他占位 */
.dsj-leave-active {
position: absolute;
}
/* 针对其他移动的阶段需要 */
.dsj-move {
transition: all 2s ease;
}
v-move 针对其他动画
必须有 key
npm i underscore 打乱数字的 js 库