一、基于 height 实现动画(1)
当起始位置有一个 height 为
auto时,不会有动画效果,因为 transition 这个属性需要起始位置的确切数值,才能计算出相应的动画。一般来说,设置display: none时,height 就为 auto。解决方法为:设置height:0,同时,如果有子元素,还要设置overflow:hidden。当然,在某些情况,也需要结合opacity这个属性来使用。最后,也不能用visibility: hidden来替代 display:none,因为前一个属性只是隐藏了元素,但位置还占着。下面是项目中的一些代码,仅供参考:
// html。简略结构。
<div>
<div class="rigisterMain">注册</div>
<div class="loginMain">登录</div>
<button @click="switchComp($event)">切换组件</button>
</div>
// less。第一次加载页面时,隐藏创建账户组件。
.rigisterMain {
height: 0;
overflow: hidden; // 有子组件
}
.loginMain {
overflow: hidden; // 提前设置默认值
}
// vue.js
switchComp(e) {
const rigisterEl = document.querySelector(".rigisterMain")
const loginEl = document.querySelector(".loginMain")
const rigisterHeight = getComputedStyle(rigisterEl, null)['height']
const loginHeight = getComputedStyle(loginEl, null)['height']
if (rigisterHeight === "0px" && e.target._prevClass === "rigisterTitle") {
rigisterEl.style = `height:${loginHeight}; opacity:1`
loginEl.style = `height:0px; opacity:0`
} else if (loginHeight === "0px" && e.target._prevClass === "loginTitle") {
loginEl.style = `height:${rigisterHeight}; opacity:1`
rigisterEl.style = `height:0; opacity:0`
}
},
二、基于 height 实现动画(2)
将元素的原始样式设置为
height:0; opacity:0; overflow: hiddern,然后再通过绑定 class 的方式,让元素隐藏或显示,并设置显示元素的样式height:?px; opacity:1,最后,在对应的标签的上设置transition属性,即可实现动画效果。(关键还是要知道起始的高度,该方法优于第一种。)
// html
<div>
<div :class="{show: showRigister}">注册</div>
<div :class="{show: showLogin}">登录</div>
<button @click="switchComp($event)">切换组件</button>
</div>
// less
main {
transition: height 1s ease-in-out;
height: 0;
overflow: hidden;
opacity: 0;
&.show {
height: 151px; // 高度是固定值,经计算得到。
opacity: 1;
}
}
// vue.js
data() {
return {
showRigister: false,
showLogin: true
}
},
methods: {
switchComp(e) {
if (e.target._prevClass === "rigisterTitle") {
this.showRigister = true
this.showLogin = false
} else {
this.showRigister = false
this.showLogin = true
}
}
}
三、基于 opacity 和 transform 实现动画
这种方法主要是使用了 vue 里面的
Transition组件,通过该组件,可以获取到 6 个 class,然后在里面设置opacity | transform | transition | animation等动画属性。值得注意的是,该组件必须结合v-if和v-show来使用,否则那 6 个 class 不会被添加到元素上。最后,这个组件无法对基于height来实现动画效果,因为使用 v-if 后,无初始高度,使用 v-show 后,初始高度为auto。
// html
<div>
<transition name="fade1">
<main v-show="showRigister">Rigister<main>
</transition>
<transition name="fade2">
<main v-show="showLogin">Login<main>
</transition>
<button @click="switchComp($event)">切换组件</button>
</div>
// less
main{
&.fade1-leave-to, &.fade2-leave-to {
opacity: 0;
}
&.fade1-enter-to {
opacity: 0.8;
}
&.fade2-enter-to {
transform: translateY(-151px);
}
&.fade1-enter-active, &.fade2-enter-active,
&.fade1-leave-active, &.fade2-leave-active {
transition: all 1s ease;
}
}
// vue.js
export default {
data() {
return {
showRigister: false,
showLogin: true
}
},
methods: {
switchComp(e) {
if (e.target._prevClass === "rigisterTitle") {
this.showRigister = true
this.showLogin = false
} else {
this.showRigister = false
this.showLogin = true
}
}
}
}