本文基于vue官方文档,分别为:动态组件 & 异步组件、插槽、进入/离开 & 列表过渡 章节连接描述html
要想实现tab动画,首先要了解vue中哪些元素/那些组件适合在那些条件下实现动画效果
vue官方文档中有这样一个例子vue
<div id="demo"> <button v-on:click="show = !show"> Toggle </button> <transition name="fade"><!--用transition包裹要添加动画的元素/组件--> <p v-if="show">hello</p> </transition> </div>
当你在transition上添加指定的name后,vue在进入/离开的过渡中,会有 6 个 class 切换,分别为:
name-enter、name-enter-active、name-enter-to、name-leave、name-leave-active、name-leave-togit
如图所示:github
v-enter:定义进入过渡的开始状态。在元素被插入以前生效,在元素被插入以后的下一帧移除。v-enter-active:定义进入过渡生效时的状态。在整个进入过渡的阶段中应用,在元素被插入以前生效,在过渡/动画完成以后移除。这个类能够被用来定义进入过渡的过程时间,延迟和曲线函数。数组
v-enter-to: 2.1.8版及以上 定义进入过渡的结束状态。在元素被插入以后下一帧生效 (与此同时 v-enter
被移除),在过渡/动画完成以后移除。缓存v-leave: 定义离开过渡的开始状态。在离开过渡被触发时马上生效,下一帧被移除。异步
v-leave-active:定义离开过渡生效时的状态。在整个离开过渡的阶段中应用,在离开过渡被触发时马上生效,在过渡/动画完成以后移除。这个类能够被用来定义离开过渡的过程时间,延迟和曲线函数。ide
v-leave-to: 2.1.8版及以上 定义离开过渡的结束状态。在离开过渡被触发以后下一帧生效 (与此同时 v-leave
被删除),在过渡/动画完成以后移除。函数
因此咱们要想实现tab切换动画,只须要在transition中添加咱们每一个单独tab页的子组件动画
1.用ul(无序列表)建立tab上方导航
<ul class="tabNav"> <li v-for="(item, index) in tabs" :class="{'active' : tabIndex === index}" @click="changeTab(index)">{{item.desc}}</li> </ul>
data中的定义
data () { return { currentTabComponent: 'tab1', // tab页默认显示第一项 tabIndex: 0, transitionName: '' // tab根据既定格式定义 tabs: [ { id: 'tab1', desc: '首页' }, { id: 'tab2', desc: '联系咱们' }, { id: 'tab3', desc: '与我相关' } ] } },
设置li横向排布,我建立的时候是把每一个导航名称放在data里,用v-for作循环
2.具体设置每一个tab页
<!-- slot中间表示插槽内容为空时显示的默认值 -->
<!-- 每个tab页的展现, keep-alive使得标签的组件实例可以在它们第一次被建立的时候缓存下来-->
<div class="content"> <keep-alive> <transition :name="transitionName"> <component v-bind:is="currentTabComponent"></component> </transition> </keep-alive> </div>
组件功能是vue项目的一大特点。组件能够扩展html元素,能够封装可重用的代码。咱们用is特性来扩展,从而达到能够在这些受限制的html元素中使用。is会将currentTabComponent的值转换成指定的组件形式:
若是currentTabComponent为my-component
<component v-bind:is="currentTabComponent"></component>
转化后为:<my-component></mu-component>
在tab导航点击时修改tabIndex,此时监听tabIndex的变化,当目的值>原始值,向右滑动,反之向左滑动
tabIndex (to, from) { let that = this; that.transitionName = (to > from) ? 'forward' : 'backward'; }
设置vue动画六个状态的class的效果,此项目中由于存在两种滑动状态,因此有12个class
.forward-enter-active,.forward-leave-active{ transition: 0.5s all ease; transform: translateX(0); } .forward-enter{ transform: translateX(100%); } .forward-enter-to{ transform: translateX(0); } .forward-leave { transform: translate3d(0, 0, 0); } .forward-leave-to { transform: translate3d(-100%, 0, 0); } .backward-enter-active, .backward-leave-active { transition: all 0.5s; } .backward-leave { transform: translate3d(0, 0, 0); } .backward-leave-to { transform: translate3d(100%, 0, 0); } .backward-enter { transform: translate3d(-100%, 0, 0); } .backward-enter-to { transform: translate3d(0, 0, 0); }
遇到问题:
在两个tab页相互切换时,当前div没被移走,将会致使下一个将会一直存在于当前div消失才一上来,因此我用了position:absolute,使每一个div都飘在上面,可是遇到的问题是最外层的盒子不能随内层单个tab页高度变化,因此我用了js动态把tab页高度赋值给外层div,目前还没想到更好的方案。
最后我封装了一下组件,使用时只须要传入tab的标题数组和单独的tab页便可使用
⚠️:github地址可查看代码github