Vue3无第三方库实现Props驱动的进度条动画方案求助
问题:Vue中实现动态关键帧进度条(无需第三方库/额外JS)
我希望在VueJS中实现如下所示的进度条效果,且不使用第三方库或额外JavaScript代码:
目标静态效果代码
CSS
#progress { width: 200px; background: #E6E6E6; height: 16px; position: relative; &::after { display: block; position: absolute; inset: 0; width: 0; background: red; content: ''; animation: forwards .3s ease-in progress-further; } } @keyframes progress-further { to { width: 70%; } }
HTML
<div id="progress"></div>
关键帧中的70%数值需要从组件Props中获取,使进度条增长到指定阈值。我尝试使用v-bind绑定,但关键帧无法生效。也查看过Transition组件,但似乎不符合需求。
我尝试的无效代码
<script> const props = defineProps({ value: { type: Number, required: true, validator: (value: number) => value >= 0 && value <= 100 } }) const formatProgressAsCssPercentage = computed(() => `${props.value}%`) </script> <style> @keyframes progress-forwards { to { width: v-bind(formatProgressAsCssPercentage); } } </style>
解决方案
方法1:CSS变量 + v-bind(适配原关键帧逻辑)
Vue支持通过v-bind绑定CSS变量,再在关键帧中引用变量,以此实现动态控制关键帧目标值:
<script setup> const props = defineProps({ value: { type: Number, required: true, validator: (value) => value >= 0 && value <= 100 } }) const progressPercent = computed(() => `${props.value}%`) </script> <template> <div id="progress" :style="{ '--target-width': progressPercent }"></div> </template> <style scoped> #progress { width: 200px; background: #E6E6E6; height: 16px; position: relative; &::after { display: block; position: absolute; inset: 0; width: 0; background: red; content: ''; animation: forwards .3s ease-in progress-further; } } @keyframes progress-further { to { width: var(--target-width); } } </style>
方法2:不用关键帧,直接用transition过渡
如果不需要复杂关键帧逻辑,可直接通过动态绑定width配合transition实现,代码更简洁:
<script setup> const props = defineProps({ value: { type: Number, required: true, validator: (value) => value >= 0 && value <= 100 } }) const progressWidth = computed(() => `${props.value}%`) </script> <template> <div class="progress-container"> <div class="progress-bar" :style="{ width: progressWidth }"></div> </div> </template> <style scoped> .progress-container { width: 200px; height: 16px; background: #E6E6E6; overflow: hidden; } .progress-bar { height: 100%; background: red; width: 0; transition: width .3s ease-in; } </style>
原代码无效原因
Vue的v-bind无法直接绑定@keyframes内的属性值,因为CSS关键帧的解析时机与Vue响应式变量的注入时机不匹配,通过CSS变量作为中间层即可解决该问题。
内容的提问来源于stack exchange,提问作者Symtox
相关产品推荐
相关产品推荐

