vue.js - Vue.js 精确的 CSS 类切换以重新触发 CSS 动画
问题描述
我遇到了 Vue.js 的问题,nextTick()
似乎没有按预期工作。
我有以下 HTML 代码
<q-icon
color='grey-7'
:name="connectionStateIcon"
class="icon-reconnect"
:class='[$storage.state.websocket.state, reconnect_pulse]'></q-icon>
其中connectionStateIcon
是一个计算属性,它选择当前连接状态的图标,$storage.state.websocket.state
保存当前连接状态(打开、关闭...)的文本表示,用于选择一个 CSS 定义(即.q-icon.icon-reconnect.open
)应用某个基础图标的颜色,reconnect_pulse
是一个data
用于触发动画的变量。
每当触发新的重新连接尝试时,应该运行动画,并且reconnect_pulse
应该从类转换''
到'reconnectpulse'
以触发动画。
data: function () {
return {
reconnect_pulse: '',
}
},
created() {
this.$eventbus.$on('connection-state', (state) => {
if (state == 'reconnecting') {
this.reconnect_pulse = ''; // remove the class `reconnectpulse`
this.$nextTick(() => { this.reconnect_pulse = 'reconnectpulse'; }); // add the class `reconnectpulse` to trigger the animation
//setTimeout(() => { this.reconnect_pulse = 'reconnectpulse'; }, 100) // this works, and more reliably, the bigger the timeout is.
}
})
},
CSS如下:
@keyframes reconnectpulse {
from { color:#ffa000; } to { } /* from orange to whichever base color the icon has */
}
.q-icon.reconnectpulse {
animation: reconnectpulse 2.0s ease-in; /* the above animation's properties */
}
.q-icon.icon-reconnect { } /* "grey-7" is default base color */
.q-icon.icon-reconnect.open {
color: yellowgreen; /* when the connection is established, select green as the base color */
}
我的问题是,我假设this.$nextTick
Vue 完成执行删除 CSS 类的当前滴答后,将立即执行 's 代码reconnectpulse
,以便在下一个滴答reconnectpulse
中可以再次应用,然后触发 DOM动画。
但由于某种原因,这只适用于一次。如果我用相对较大的超时替换this.$nextTick
为setTimeout
,以便元素reconnectpulse
在重新应用之前将类删除足够长的时间,那么它就可以工作。超时时间为 20 毫秒,它有时工作,有时不工作,只有一次 0 毫秒(因为初始值为reconnect_pulse
is ''
),每次 100 毫秒。
很奇怪的是,我目前正在重写Vue组件,而旧版本的asetTimeout
为0ms,而且每次都能正常工作。我不知道究竟有哪些区别,因为旧代码有些混乱,但本质上,关于动画的代码是相同的。
我希望this.$nextTick
能够以setTimeout
非常精确的方式进行替换,但它不起作用,而且我不擅长手动调整setTimeout
' 延迟,因为这可能因设备而异。
this.$nextTick
在这种情况下有什么问题?在不使用的情况下,我还能做些什么来存档所需的效果setTimeout
?
直接访问元素时也是如此:
_.forEach(document.querySelectorAll('.icon-reconnect'), (icon) => {
icon.classList.remove('reconnectpulse')
})
setTimeout(() => {
_.forEach(document.querySelectorAll('.icon-reconnect'), (icon) => {
icon.classList.add('reconnectpulse')
})
}, 100)
然后我期待以下工作(但它没有):
_.forEach(document.querySelectorAll('.icon-reconnect'), (icon) => {
icon.classList.remove('reconnectpulse')
icon.classList.add('reconnectpulse')
})
解决方案
一种解决方案是在重新应用之前不清除该类,而是将其替换为另一个具有相同动画属性的类。
<q-icon
color='grey-7'
:name="connectionStateIcon"
class="icon-reconnect"
:class='[$storage.state.websocket.state, reconnect_pulse]'></q-icon>
data: function () {
return {
reconnect_pulse: '',
}
},
created() {
this.$eventbus.$on('connection-state', (state) => {
if (state == 'reconnecting') {
if (this.reconnect_pulse != 'reconnect-pulse-tick') {
this.reconnect_pulse = 'reconnect-pulse-tick'
}
else {
this.reconnect_pulse = 'reconnect-pulse-tock'
}
}
})
},
@keyframes reconnect-pulse-tick {
from { color:#ffa000; } to { }
}
.q-icon.reconnect-pulse-tick {
animation: reconnect-pulse-tick 2.0s ease-in;
}
@keyframes reconnect-pulse-tock {
from { color:#ffa000; } to { }
}
.q-icon.reconnect-pulse-tock {
animation: reconnect-pulse-tock 2.0s ease-in;
}
.q-icon.icon-reconnect { } /* "grey-7" is default base color */
.q-icon.icon-reconnect.open {
color: yellowgreen; /* when the connection is established, select green as the base color */
}
在这种情况下,重要的是动画关键帧也有不同的名称,如上面的 css 代码所示。
TBH,我实际上更喜欢这个解决方案,而不是尝试使用nextTick
or的解决方案setTimeout
。
推荐阅读
- flutter - 更改 Flutter PopupMenu 大小
- java - Arduino蓝牙模块HC-05和Androidstudio app之间的连接
- python-3.x - 如何在 python 3 中异或字节
- arm - 是否有带有 ARM Cortex m3、4、7 和 Canbus 接口的硬件模块可用于小批量项目?
- reactjs - 如何在 React 中使用 HOC 从链接到页面到父页面的参数中获取 id 以获取数据
- python - 运行 tf.distribute MultiWorkerMirroredStrategy 时出现“地址已在使用”错误。如何使用端口杀死进程
- python - 在 python 中使用 itertools 创建一个单词列表,我怎样才能让它在单词列表而不是当前硬编码的 word_list[0] 上工作?
- database - 循环数据,如果满足条件则复制到新工作表
- amazon-web-services - 多个 AWS Lambda 中的 AWS::S3::Bucket LambdaConfiguration
- r - 根据变量的递减值绘制