要弄一个css3动画,首先要搞清楚4个状态,分别是enter enter-to leave leave-to即 开始前、到达目标、离开前、离开结束。并且对应有6个事件钩子before-enter enter after-enter before-leave leave after-leave大致流程如下:

有了基本状态,接着就是通过阶段性去修改对应的样式即可。
- 基础样式:
.transition {
-webkit-transition-duration: 300ms; transition-duration: 300ms;
transition-timing-function: ease;
}
// 过渡属性 fade
.le-fade-enter-active,
.le-fade-leave-active {
transition-property: opacity;
}
// 初始值 & 结束目标值
.le-fade-enter,
.le-fade-leave-to {
opacity: 0;
}
- 利用promise 去模拟状态变化过程
// 阶段类名
const getClassNames = function(moveName) {
return {
enter: `le-${moveName}-enter le-${moveName}-enter-active enter-class enter-active-class`,
"enter-to": `le-${moveName}-enter-to le-${moveName}-enter-active enter-to-class enter-active-class`,
leave: `le-${moveName}-leave le-${moveName}-leave-active leave-class leave-active-class`,
"leave-to": `le-${moveName}-leave-to le-${moveName}-leave-active leave-to-class leave-active-class`
};
};
// nextTick 事件模拟
const nextTick = () => new Promise(resolve => setTimeout(resolve, 1000 / 30));
methods: {
enter() {
const { duration, name } = this.data;
const classNames = getClassNames(name);
this.status = "enter";
this.$emit("before-enter");
// 过程模拟
Promise.resolve()
.then(nextTick)
.then(() => {
this.$emit("enter");
this.setData({
currClass: classNames.enter,
display: true
});
})
.then(nextTick)
.then(() => {
this.transitionEnded = false;
// 微信动画结束时会回调onTransitionEnd 以下是为了兼容处理
setTimeout(() => this.onTransitionEnd(), duration);
this.setData({
currClass: classNames["enter-to"]
});
})
.catch(() => {});
},
leave() {
if (!this.data.display) return false;
const { duration, name } = this.data;
const classNames = getClassNames(name);
this.status = "leave";
this.$emit("before-leave");
Promise.resolve()
.then(nextTick)
.then(() => {
this.$emit("leave");
this.setData({
currClass: classNames.leave
});
})
.then(nextTick)
.then(() => {
this.transitionEnded = false;
setTimeout(() => this.onTransitionEnd(), duration);
this.setData({
currClass: classNames["leave-to"]
});
});
},
onTransitionEnd() {
// 兼容处理 小程序会回调
if (this.transitionEnded) return;
this.transitionEnded = true;
this.$emit(`after-${this.status}`);
const { show, display } = this.data;
if (!show && display) {
this.setData({ display: false });
}
}
}
- 最后调整调整就ok 了