Vue之过渡与动画---kalrry
一、过渡
Vue 在插入、更新或者移除 DOM 时,提供多种不同方式的应用过渡效果。
Vue 提供了内置的过渡封装组件,该组件用于包裹要实现过渡效果的组件。
语法格式:
<transition name = "nameoftransition">
<div></div>
</transition>
实例:列表元素的添加与删除
<style type="text/css">
li {
border: 1px red dashed;
line-height: 15px;
font-size: 12px;
padding: 10px;
}
li:hover {
background-color: skyblue;
transition: all 0.3s;
}
.v-enter,
.v-leave-to {
opacity: 0;
transform: translateY(80px);
}
.v-enter-active,
.v-leave-active {
transition: all 0.6s ease;
}
/* 下面两个搭配使用,可以使下面的列表项有个飘上来的效果 */
.v-move{
transition: all 0.6s ease;
}
.v-leave-active{
position: absolute;
}
</style>
<title>Document</title>
</head>
<body>
<div id="app">
ID:<input type="text" v-model="id" />
NAME:<input type="text" v-model="name" />
<input type="button" value="提交" v-on:click="add" />
<ul>
<transition-group>
<li v-for="(item,i) in list" :key="item.id" v-on:click="del(i)">
{
{
item.id}}------{
{
item.name}}
</li>
</transition-group>
</ul>
</div>
<script>
new Vue({
el: '#app',
data: {
id: '',
name: '',
list: [{
id: 1,
name: '李白'
},
{
id: 2,
name: '杜甫'
},
{
id: 3,
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>
过渡其实就是一个淡入淡出的效果。Vue在元素显示与隐藏的过渡中,提供了 6 个 class 来切换:
1. v-enter
定义进入过渡的开始状态。在元素被插入之前生效,在元素被插入之后的下一帧移除。
2. v-enter-active
定义进入过渡生效时的状态。在整个进入过渡的阶段中应用,在元素被插入之前生效,在过渡/动画完成之后移除。这个类可以被用来定义进入过渡的过程时间,延迟和曲线函数。
3. v-enter-to
2.1.8版及以上 定义进入过渡的结束状态。在元素被插入之后下一帧生效 (与此同时 v-enter 被移除),在过渡/动画完成之后移除。
4. v-leave
定义离开过渡的开始状态。在离开过渡被触发时立刻生效,下一帧被移除。
5. v-leave-active
定义离开过渡生效时的状态。在整个离开过渡的阶段中应用,在离开过渡被触发时立刻生效,在过渡/动画完成之后移除。这个类可以被用来定义离开过渡的过程时间,延迟和曲线函数。
6. v-leave-to
2.1.8版及以上 定义离开过渡的结束状态。在离开过渡被触发之后下一帧生效 (与此同时 v-leave 被删除),在过渡/动画完成之后移除。
注:
1、对于这些在过渡中切换的类名来说,如果你使用一个没有名字的 ,则 v- 是这些类名的默认前缀。如果你使用了 <transition name=“my-transition”>,那么 v-enter 会替换为 my-transition-enter。
2、 transition 只有 name 这一个属性,且只有一个子元素,这个子元素需要 v-if 或 v-show 来控制是否显示
3、 现在一般只使用 v-ente、v-enter-active、v-leave-active、v-leave-to
4、 transition只适用于单个元素,对于多个元素使用transition-group
二、CSS 动画
CSS 动画用法类似 CSS 过渡,但是在动画中 v-enter 类名在节点插入 DOM 后不会立即删除,而是在 animationend 事件触发时删除。
1. 只修改name的值和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);
}
}
2. @keyframes
@keyframes是CSS创建动画的规则
自定义过渡的类名,我们可以通过以下特性来自定义过渡类名:
enter-class 、enter-active-class 、enter-to-class 、leave-class 、leave-active-class 、leave-to-class
自定义过渡类名的优先级高于普通的类名,这对于 Vue 的过渡系统和其他第三方 CSS 动画库,如 Animate.css 结合使用十分有用。
<div id = "databinding">
<button v-on:click = "show = !show">点我</button>
<transition
name="custom-classes-transition"
enter-active-class="animated tada"
leave-active-class="animated bounceOutRight"
>
<p v-if="show">菜鸟教程 -- 学的不仅是技术,更是梦想!!!</p>
</transition>
</div>
<script type = "text/javascript">
new Vue({
el: '#databinding',
data: {
show: true
}
})
</script>
注:
name属性值是自定义的, enter-active-class和leave-active-class的值是animated库中定义的动画
3. 使用第三方动画库(animate.css)
实例
<div id="app">
<input type="button" value="toggle" v-on:click="flog=!flog" />
<transition enter-active-class="animated bounceIn" leave-active-class="animated bounceOut">
<h3 v-show="flog">显示与隐藏</h3>
</transition>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
flog: false
}
})
</script>
只需要引入animate.css,然后选择相应的动画类即可
//使用跳入与跳出动画,动画类名前加上基类animated
<transition enter-active-class="animated bounceIn" leave-active-class="animated bounceOut">
//除此之外还可以使用:duration指定动画事件
<transition enter-active-class="animated bounceIn" leave-active-class="animated bounceOut" :duration="200"> 进入与出去都是200ms
<transition enter-active-class="animated bounceIn" leave-active-class="animated bounceOut" :duration="{enter:200,leave:400}"> 分别设置
4. 使用JavaScript 钩子实现动画
可以在属性中声明 JavaScript 钩子:
<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>
然后在vue中定义相应的方法
实例:模拟小球半场动画
<div id="app">
<button v-on:click="flog=!flog">快到碗里来</button>
<transition @before-enter="beforeEnter" @enter="enter" @after-enter="afterEnter">
<div class="ball" v-show="flog"></div>
</transition>
</div>
<script>
new Vue({
el: '#app',
data: {
flog: false
}, methods: {
beforeEnter(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()
},
afterEnter(el) {
console.log(this.flog)
this.flog = !this.flog
console.log(this.flog)
}
},
})
</script>
注:
这些钩子函数可以结合 CSS transitions/animations 使用,也可以单独使用。
当只用 JavaScript 过渡的时候,在 enter 和 leave 中必须使用 done 进行回调。否则,它们将被同步调用,过渡会立即完成。
推荐对于仅使用 JavaScript 过渡的元素添加 v-bind:css=“false”,Vue 会跳过 CSS 的检测。这也可以避免过渡过程中 CSS 的影响。
多个元素的过渡
我们可以设置多个元素的过渡。需要注意的是当有相同标签名的元素切换时,需要通过 key 特性设置唯一的值来标记以让 Vue 区分它们,否则 Vue 为了效率只会替换相同标签内部的内容。
<transition>
<button v-if="isEditing" key="save">
Save
</button>
<button v-else key="edit">
Edit
</button>
</transition>
或
<transition>
<button v-bind:key="isEditing">
{
{
isEditing ? 'Save' : 'Edit' }}
</button>
</transition>
对于多重条件判断可以这样:
<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'
}
}
}