环形加载进度条怎么在Vue里实现动态旋转?
我用Vue做了一个环形加载动画,但转起来特别卡,而且方向不对,明明写了顺时针却逆着转。是不是transform-origin没设对?
试过用CSS animation配合transition,也试过直接改style,都不太行。下面是我现在用的代码:
<template>
<div class="loading-ring" :style="{ transform: rotate(${angle}deg) }"></div>
</template>
<script setup>
import { ref, onMounted } from 'vue'
const angle = ref(0)
onMounted(() => {
setInterval(() => angle.value += 6, 100)
})
</script>
问题一:模板字符串语法错误
你的 :style 写法有问题,Vue 的绑定语法不能直接嵌套模板字符串。应该这样写:
问题二:性能卡顿的根源
用 setInterval 每 100ms 触发一次 Vue 响应式更新来改角度,这种做法太笨重了。每秒 10 次重新渲染,浏览器压力很大。环形加载动画应该直接用 CSS animation,JS 只需要控制动画的开始停止就行,完全不需要逐帧更新角度。
问题三:方向问题
纯 CSS 写
rotate(360deg)是顺时针,负值才是逆时针。你说逆着转大概率是 transform-origin 没设对,或者你的环形是用 SVG 画的,SVG 坐标系和 CSS 坐标系方向相反。正确的实现思路:
环形加载条有两种常见做法,我给你分别写一下:
方案一:纯 CSS + 双半圆(推荐)
这是最简单性能也最好的,用两个半圆 div 通过 animation 交替显示:
方案二:SVG stroke-dasharray(更精确控制进度)
如果你的环形是要显示具体进度的,用 SVG 更合适:
关于方向的问题再说一下:
如果你用的是方案二的 SVG,记住 stroke-dashoffset 是顺时针减少的,SVG 的 y 轴方向和 CSS 不太一样。如果发现方向反了,把
stroke-dashoffset的计算改成progress.value / 100 * circumference而不是减法,或者直接在 SVG 元素上加transform: scaleX(-1)翻转一下。最后提醒一下,方案一完全不需要 JS 介入,纯 CSS 就能跑,性能最好。方案二如果你只需要无限循环的加载动画,也可以直接用 CSS animation 旋转 SVG,不需要 JS 计算 progress。