You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 18:32:37