Vue中的动画
多元素的过渡
v-if
/v-else
的元素切换
- 标签名不同
<transition>
<table v-if="items.length > 0">
<!-- ... -->
</table>
<p v-else>Sorry, no items found.</p>
</transition>
- 标签名相同
需要通过key设置唯一的值来标记让Vue区分它们,否则,Vue为了效率只会替换相同标签内部的内容。(该内容适用于其他插值表达式运用时)
<transition>
<button v-if="isEditing" key="save">
Save
</button>
<button v-else key="edit">
Edit
</button>
</transition>
过渡模式
以上知识运用时,出现问题:删除列表项时 或者 点击开按钮出现关按钮的动画 突兀
同时生效的进入和离开的过渡不能满足所有要求,所以Vue提供了过渡模式
- in-out:新元素先进行过渡,完成之后当前元素过渡离开。
- out-in:当前元素先进行过渡,完成之后新元素过渡进入。
例子:
<transition mode="out-in">
<!-- ...... -->
</transition>
v-for 的列表过渡
- 定义过渡样式:
<style>
.list-enter,
.list-leave-to {
opacity: 0;
transform: translateY(10px);
}
.list-enter-active,
.list-leave-active {
transition: all 0.3s ease;
}
</style>
- 定义DOM结构,其中,需要使用 transition-group 组件把v-for循环的列表包裹起来:
<div id="app">
<input type="text" v-model="txt" @keyup.enter="add">
<transition-group tag="ul" name="list">
<li v-for="(item, i) in list" :key="i">{{item}}</li>
</transition-group>
</div>
- 定义 VM中的结构:
// 创建 Vue 实例,得到 ViewModel
var vm = new Vue({
el: '#app',
data: {
txt: '',
list: [1, 2, 3, 4]
},
methods: {
add() {
this.list.push(this.txt);
this.txt = '';
}
}
});
列表过渡
- 在实现列表过渡的时候,如果需要过渡的元素,是通过
v-fo
r 循环渲染出来的,不能使用 transition 包裹,需要使用transition-group
- 通过 为
transition-group
元素,设置tag
属性,指定 transition-group 渲染为指定的元素,如果不指定 tag 属性,默认,渲染为span
标签。浏览器查看源代码时,可能查看到不符合html的结构的代码。 - 过渡模式不可用,因为我们不再相互切换特有的元素。
- 内部元素 总是需要 提供唯一的
key
属性值。 - CSS 过渡的类将会应用在内部的元素中,而不是这个组/容器本身。
但当添加和移除元素的时候,周围的元素会瞬间移动到他们的新布局的位置,而不是平滑的过,列表的排序过渡解决该问题
列表的排序过渡
<transition-group>
组件还有一个特殊之处。不仅可以进入和离开动画,还可以改变定位。要使用这个新功能只需了解新增的 v-move
特性,它会在元素的改变定位的过程中应用。
v-move
和v-leave-active
结合使用,能够让列表的过渡更加平缓柔和:
.v-move{
transition: all 0.8s ease;
}
.v-leave-active{
position: absolute;
}
多组件过渡
使用flag
标识符结合v-if
和v-else
切换组件
- HTML结构
<div id="app">
<a href="" @click.prevent="flag=true">登录</a>
<a href="" @click.prevent="flag=false">注册</a>
<login v-if="flag"></login>
<register v-else="flag"></register>
</div>
- Vue实例定义:
<script src="./lib/vue-2.4.0.js"></script>
<script>
Vue.component('login', {
template: '<h3>登录组件</h3>'
})
Vue.component('register', {
template: '<h3>注册组件</h3>'
})
// 创建 Vue 实例,得到 ViewModel
var vm = new Vue({
el: '#app',
data: {
flag: false
},
methods: {}
});
</script>
使用:is
属性来切换不同的子组件
- HTML结构
<div id="app">
<a href="" @click.prevent="comName='login'">登录</a>
<a href="" @click.prevent="comName='register'">注册</a>
<component :is="comName"></component>
</div>
- Vue实例定义:
<script>
// 组件名称是 字符串
Vue.component('login', {
template: '<h3>登录组件</h3>'
})
Vue.component('register', {
template: '<h3>注册组件</h3>'
})
// 创建 Vue 实例,得到 ViewModel
var vm = new Vue({
el: '#app',
data: {
comName: 'login' // 当前 component 中的 :is 绑定的组件的名称
},
methods: {}
});
</script>
结合:is
属性,添加动画
- 修改HTML结构
<div id="app">
<a href="#" @click.prevent="comName='login'">登录</a>
<a href="#" @click.prevent="comName='register'">注册</a>
<hr>
<transition mode="out-in">
<component :is="comName"></component>
</transition>
</div>
- 添加切换样式:
<style>
.v-enter,
.v-leave-to {
opacity: 0;
transform: translateX(30px);
}
.v-enter-active,
.v-leave-active {
position: absolute;
transition: all 0.3s ease;
}
h3{
margin: 0;
}
</style>