Vue 在插入、更新或者移除 DOM 时,提供多种不同方式的应用过渡效果。(能够触发的包括 v-if、 v-show 、数据更新导致的页面更新、组件过渡等)
1. 在 CSS 过渡和动画中自动应用 class
Vue 提供了 transition 的封装组件,在下列情形中,可以给任何元素和组件添加进入/离开过渡
- 条件渲染 (使用 v-if)
- 条件展示 (使用 v-show)
- 动态组件
- 组件根节点
用法:将要加过渡效果的元素包裹在<transition></transition>
标签里,添加css类即可达成动画过渡效果
/*动画进入之前和离开之后的状态*/
.v-enter,
.v-leave-to {
opacity: 0;
transform: translateX(80px);
}
/*动画进入过程和离开过程的状态*/
.v-enter-active,
.v-leave-active{
transition: all 0.4s ease;
}
当插入或删除包含在 transition
组件中的元素时,Vue 将会做以下处理:
-
自动嗅探目标元素是否应用了 CSS 过渡或动画,如果是,在恰当的时机添加/删除 CSS 类名。
-
如果过渡组件提供了 JavaScript 钩子函数,这些钩子函数将在恰当的时机被调用。
-
如果没有找到 JavaScript 钩子并且也没有检测到 CSS 过渡/动画,DOM 操作 (插入/删除) 在下一帧中立即执行。(注意:此指浏览器逐帧动画机制,和 Vue 的
nextTick
概念不同)
2. 可以配合使用第三方 CSS 动画库,如 Animate.css
使用方式:导入Animate.css动画库
<link rel="stylesheet" href="./animate3.5.2.css">
在 transition
标签中添加 Animate.css 内置类,绑定 duration 属性可以指定入场和出场动画的时间
<transition enter-active-class="animated bounceIn" leave-active-class="animated bounceOut" :duration="{ enter: 400, leave: 800 }">
<h1 v-show="flag">h1标签</h1>
</transition>
3. 在过渡钩子函数中使用 JavaScript 直接操作 DOM
钩子函数有以下这些
<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>
每一个钩子函数绑定一个函数,在函数中可以给元素设置样式和过渡效果
methods: {
beforeEnter (el) {
// 动画入场之前绑定的函数,动画还未开始,el表示设置了过渡效果的当前元素,可以通过 el 设置动画入场之前的样式
el.style.transform = "translate(0, 0)";
},
enter (el, done) {
// 表示动画开始绑定的函数,可以设置小球在动画结束之后的状态
// 这句话没有实际的作用,但是不写就没有动画效果
el.offsetWidth;
el.style.transform = "translate(150px, 450px)";
el.style.transition = "all 1s ease";
// done 即代表 after-enter 中绑定的函数
done();
},
afterEnter (el) {
// 动画完成之后
this.flag = !this.flag;
}
}
也可以配合使用第三方 JavaScript 动画库,如 Velocity.js。
注意:这里的例子只写了上半场的动画,即进入的动画的钩子函数,离开的没有写,所以在结束上半场动画时,要让它回到初始状态,这样是为了跳过下半场动画,否则会出现一个错误
4. 给列表添加过渡
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>过渡</title>
<style>
ul li{
border: 1px dashed #ccc;
line-height: 30px;
font-size: 12px;
padding-left: 15px;
margin-top: 5px;
width: 100%;
}
li:hover{
background-color: skyblue;
transition: all 0.8s ease;
}
/*动画进入之前和离开之后的状态*/
.v-enter,
.v-leave-to {
opacity: 0;
transform: translateY(80px);
}
/*动画进入过程和离开过程的状态*/
.v-enter-active,
.v-leave-active{
transition: all 0.4s ease;
}
.v-move{
transition: all 0.4s ease;
}
.v-leave-active{
position: absolute;
}
</style>
</head>
<body>
<!-- 这是 MVVM 中的 V 视图-->
<div id="zz">
<label>
ID:
<input type="text" v-model="id">
</label>
<label>
ID:
<input type="text" v-model="name">
</label>
<button @click="add">添加</button>
<!-- <ul> -->
<!--在for循环中包裹的元素添加动画用 transitionGroup-->
<!-- appear 可以设置元素初始渲染的动画效果-->
<!-- tag 设置 transition-group 标签解析为什么元素 默认是 span-->
<transition-group appear tag="ul">
<li v-for="(item, key) in list" :key="item.id" @click="del(key)">{{ item.id }} --- {{ item.name }}</li>
</transition-group>
<!-- </ul> -->
</div>
<script src="../../Vue/node_modules/vue/dist/vue.js"></script>
<script>
//1. 创建Vue的实例 这是 MVVM 中的 VM 调度者
let vm = new Vue({
el : '#zz', // 表示我们新建的 Vue 实例要控制的页面区域
data : { // data 中存放 el 中要用到的数据 ,这是 MVVM 中的 M ,保存页面的数据
list: [
{id: 1, name: "张三"},
{id: 2, name: "李四"},
{id: 3, name: "王五"},
],
id: "",
name: ""
},
methods: {
add () {
this.list.push({id: this.id, name: this.name});
this.id = this.name = "";
},
del (i) {
this.list.splice(i, 1);
}
},
});
</script>
</body>
</html>
网友评论