使用 Vue 过渡(和 CSS var() 函数)为多个元素设置动画
过渡是使您的应用具有交互性的好方法。 Vue.js 允许我们使用<transition>
组件对元素上的任何动态事件进行动画处理。但是,如果您需要为多个相互关联的元素制作动画怎么办?
[](https://res.cloudinary.com/practicaldev/image/fetch/s--svr1goq6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to- uploads.s3.amazonaws.com/uploads/articles/633se7z9bj4xtgajrod2.gif)
TLDR:CodePen 链接
当我想为图形条设置动画时,我偶然发现了这个问题。每个条都需要具有特定的宽度,并且必须在前一个之后立即进行动画处理。另外,我不想硬编码柱的数量,所以这一切都需要数据驱动。
构建数据和模板
所以让我们隔离问题,这是在 Vue 应用程序中定义条的方式:
data(){
return {
bars: [75, 50, 100]
}
}
进入全屏模式 退出全屏模式
它们在 for 循环中呈现:
<div v-for="(bar, i) in bars" :key="i" class="bar">{{bar}}%</div>
进入全屏模式 退出全屏模式
动画条使用
为它们设置动画的第一步是添加一个组件和一个根,因为这正是 Vue 所需要的:
<transition name="bars" appear>
<div>
<div v-for="(bar, i) in bars" :key="i" class="bar">{{bar}}%</div>
</div>
</transition>
进入全屏模式 退出全屏模式
注意appear
属性。它指示 Vue 在第一个(也是唯一的)子元素出现在 DOM 中时为其设置动画。 Vue 足够聪明,可以搜索应用的过渡样式,它会在过渡期间为元素添加一些特殊类:
-
bars-enter-active
为整个持续时间 -
bars-enter-from
在开始时定义 CSS 动画,例如width: 0
-
bars-enter-to
在最后定义 CSS 动画,例如width: 75%
问题是,我们需要在更细粒度的级别上定义这些属性 - 为每个条形图。
使用 var() 将数据与 CSS 连接起来
CSSvar()
函数允许我们很好地将动态数据与 CSS 连接起来。我们像元素的任何其他样式定义一样配置数据:
<div style="--variableName: variableValue"></div>
进入全屏模式 退出全屏模式
并在实际样式表中使用var(variableName)
:
.selector {
CSS property: var(--variableName);
}
进入全屏模式 退出全屏模式
在这种情况下,我们需要每个条定义其宽度并使用项目的索引计算动画延迟:
<div v-for="(bar, i) in bars" :key="i" class="bar" :style="`--width: ${bar}%; --delay: ${i}s`">{{bar}}%</div>
进入全屏模式 退出全屏模式
并添加随附的样式:
.bar {
width: var(--width);
}
.bars-enter-from .bar {
width: 0;
}
.bars-enter-active .bar {
transition: all 2s;
transition-delay: var(--delay);
}
进入全屏模式 退出全屏模式
最后要记住的是,Vue 只会在其转换中定义的时间内将特殊的 CSS 类保留在根元素上。因此,让我们将预期的动画时间添加为过渡持续时间:
<div style="`transition: all ${(bars.length-1)+2}s`">
进入全屏模式 退出全屏模式
如果 N 是条形图的数量并且每个条形图需要 2 秒来渲染,则动画将需要 N+2 秒。如果您将其设置为低于所需的值,则某些条形的动画将不会完成,只会跳到最终位置。
请参阅 CodePen 上的功能示例。
结论
--variableName: variableValue
和var(--variableName)
的组合是避免通过for
循环生成太多样式定义(即使是有限的)的好方法。
如果您想分享您的经验或取得联系,请加入Kontent Discord并给我留言😊
更多推荐
所有评论(0)