CSS关键帧动画在Vue里为什么不生效?
我在Vue组件里写了个简单的淡入动画,但页面上完全没反应,控制台也没报错。关键帧定义和animation属性都写了,是不是哪里写错了?
我试过把keyframes放在里面,也试过移到全局样式,都不行。元素本身是能正常渲染的,就是动画没效果。
<template>
<div class="fade-in">Hello Animation</div>
</template>
<style scoped>
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
.fade-in {
animation: fadeIn 2s ease-in-out;
}
</style>
scoped属性,这意味着样式只会应用到这个组件内的元素上,而不会影响全局或者其他组件。但是有时候这个作用域机制可能会导致一些意想不到的问题,尤其是在使用关键帧动画的时候。首先你要确保你的关键帧定义也被正确地作用域化。虽然大部分情况下关键帧是全局的,但在某些情况下,特别是使用
scoped的时候,可能会有问题。我们可以尝试去掉scoped属性,看看是否解决了问题。如果你不想去掉
scoped,那我们可以手动给关键帧添加一个前缀,确保它被正确地应用。我们可以通过在关键帧名称前面加上组件的唯一标识符来实现这一点。首先你要找到或者生成一个唯一的标识符,通常这个标识符是 Vue 自动生成的,看起来像这样
_v-xxxxx。你可以在浏览器的开发者工具里找到这个标识符。假设我们找到了这个标识符是
_v-abc123,那么我们可以在关键帧定义和应用的地方加上这个标识符。但是,手动添加标识符并不是一个好办法,因为它依赖于一个动态生成的字符串。更好的做法是让 Vue 自动处理这个问题。你可以通过在关键帧名称后面加上
!important来强制应用动画。不过,最简单的方法可能是直接去掉
scoped属性,除非你有非常特定的原因需要使用它。去掉scoped后,你的代码应该这样:记得保存更改后刷新页面,看看动画是否生效了。如果还是有问题,确保你的 Vue 版本是最新的,有时候版本问题也会导致一些奇怪的行为。
scoped会在CSS选择器后面加个data属性,比如编译后变成
.fade-in[data-v-xxxxx]。但@keyframes的名字是写在animation属性值里的字符串,Vue不会自动处理它,所以keyframes定义变成了@keyframes fadeIn[data-v-xxxxx],而你引用的还是fadeIn,两边对不上,动画自然不生效。解决办法很简单,把keyframes放到非scoped的区域:
或者如果你想保持scoped,可以用深度选择器:
第一种方法最省事,复制过去改一下就行。