使用vue中的过渡动画的时候:注意在使用javascript钩子的时候动画效果是无法出来的,得要额外的添加一句
el.offsetWidth
解释是这样的(非官方):
原因在于浏览器不会根据你js对style的修改实时更新,而一般是在当前js修改完毕之后,会对所有修改统一更新,而display:none(它本身是不能transition的)的状态切换影响了其他过渡效果的切换,毕竟为none的元素没法触发过渡。
将offsetWidth打开,你会发现过渡生效了,原因在于取offsetWidth导致浏览器重绘,使后面的style修改前,display确确实实变为了block,从而消除了元素状态为none对过渡的这种影响。添加setTimeout,“打断”js的执行也可生效
看看下面的代码,你觉得所有的动画都会执行吗?
beforeEnter (el) {
let top = this.state ? this.y : this.shopY
let left = this.state ? this.x : this.shopX
// 动画入场前,设置元素开始动画的起始位置
el.style.width = this.width + 'px'
el.style.height = this.height + 'px'
el.style.position = 'fixed'
el.style.left = left + 'px'
el.style.top = top + 'px'
// 动画过程禁止滚动
document.getElementsByTagName('html')[0].style.overflowY = 'hidden'
if (!this.state) {
el.style.transform = `scale(0.1)`
el.style.transformOrigin = '0 0'
this.shopDom.classList.add(this.shopAnmationClass)
}
}
// 设置完成动画之后的结束状态
enter (el, done) {
// el.offsetWidth // 强制刷新动画
console.log(el.offsetWidth)
// 结束位置
let enterX = this.x - this.shopX
let enterY = this.shopY - this.y
// 这里要考虑enterX,enterY为负数的情况
let x = this.state ? (enterX > 0 ? '-' + enterX : Math.abs(enterX)) : enterX
let y = this.state ? enterY : (enterY > 0 ? '-' + enterY : Math.abs(enterX))
let scaleNum = this.state ? '0.1' : '1'
el.style.transform = `translate(${x}px,${y}px) scale(${scaleNum})`
el.style.transformOrigin = '0 0'
el.style.transition = 'all 1s ease'
// 执行done函数,完成下面钩子函数
setTimeout(() => {
done()
}, 800)
}
这里直接使用 el.offsetWidth 会有个no-unused-expressions eslint 报错, 所以来个console.log(el.offsetWidth)eslint就不报错了。 这段代码是有问题的: 没有啦! 注意:done()这个回调函数,用于调用after-enter(after-leave) 中的逻辑,如果不需要可以不调用。本案例没有调用,所以就不展示了,当在leave中 使用了之后 动画过渡 就没了!