Vue3进度条(Progress)

📅 发布时间:2026/8/29 13:48:56
Vue3进度条(Progress) Vue2进度条Progress可自定义设置以下属性进度条宽度width单位 px类型string | number默认 undefinedtype: line 时为进度条宽度默认值 100%type: circle 时为进度圈宽高默认值 120当前进度百分比percent类型number默认 0进度条的尺寸lineSize单位 px类型number默认 undefinedtype: line 时为进度条线高默认值 8type: circle 时单位是进度圈画布宽度的百分比默认值 6进度条的色彩lineColor类型string | {0%?: string, 100%?: string, from?: string, to?: string, direction?: left|right}默认 undefined传入 string 时为纯色传入 object 时为渐变进度圈时 direction: left 为逆时针direction: right 为顺时针进度条边缘的形状lineCap类型round | square默认 round是否显示进度数值或状态图标showInfo类型boolean默认 true进度数值或状态图标的尺寸infoSize单位 px类型number默认 undefinedtype: line 时默认值 14type: circle 时默认值 undefined进度完成时的信息success类型string | slot默认 undefined内容的模板函数format类型(percent: number) (string | number) | slot默认(percent: number) percent %进度条类型type类型line | circle默认 line效果如下图在线预览①创建进度条组件Progress.vue其中引入使用了以下工具函数监听插槽存在 useSlotsExist获取依赖注入 useInjectscript setup langts import { computed } from vue import { useSlotsExist, useInject } from components/utils export interface Gradient { 0%?: string 100%?: string from?: string to?: string direction?: left | right // 默认 right } export interface Props { width?: number | string // 进度条宽度单位 pxtype: line 时为进度条宽度默认值 100%type: circle 时为进度圈宽高默认值 120 percent?: number // 当前进度百分比 lineSize?: number // 进度条的尺寸单位 pxtype: line 时为进度条线高默认值 8type: circle 时单位是进度圈画布宽度的百分比默认值 6 lineColor?: string | Gradient // 进度条的色彩传入 string 时为纯色传入 Gradient 时为渐变进度圈时 direction: left 为逆时针direction: right 为顺时针 lineCap?: round | butt // 进度条边缘的形状 showInfo?: boolean // 是否显示进度数值或状态图标 infoSize?: number // 进度数值或状态图标的尺寸单位 pxtype: line 时默认值 14type: circle 时默认值 24 success?: string // 进度完成时的信息 string | slot format?: (percent: number) string | number // 内容的模板函数 function | slot type?: line | circle // 进度条类型 } const props withDefaults(definePropsProps(), { width: undefined, percent: 0, lineSize: undefined, lineColor: undefined, lineCap: round, showInfo: true, infoSize: undefined, success: undefined, format: (percent: number) percent %, type: line }) const { colorPalettes } useInject(Progress) // 主题色注入 const slotsExist useSlotsExist([success]) // 进度条宽度/进度圈宽高 const progressSize computed(() { if (props.width undefined) { if (props.type line) { return 100% } if (props.type circle) { return 120px } } return typeof props.width number ? ${props.width}px : props.width }) // 进度条高度进度圈线宽 const progressLineSize computed(() { if (props.lineSize undefined) { if (props.type line) { return 8 } if (props.type circle) { return 6 } } return props.lineSize as number }) // 进度条/圈进度数值或状态图标尺寸 const progressInfoSize computed(() { if (props.infoSize undefined) { if (props.type line) { return 14px } if (props.type circle) { return 24px } } return ${props.infoSize}px }) // 圆条周长 const perimeter computed(() { return (100 - progressLineSize.value) * Math.PI }) // 圆条轨道路径指令 const path computed(() { const long 100 - progressLineSize.value return M 50,50 m 0,-${long / 2} a ${long / 2},${long / 2} 0 1 1 0,${long} a ${long / 2},${long / 2} 0 1 1 0,-${long} }) // 是否为渐变色 const isGradientColor computed(() { if (props.lineColor ! undefined typeof props.lineColor ! string) { return true } return false }) // 进度条/圈颜色 const lineColorComputed computed(() { if (props.lineColor undefined) { return colorPalettes.value[5] } else if (typeof props.lineColor string) { return props.lineColor } else { return linear-gradient(to ${props.lineColor.direction || right}, ${props.lineColor[0%] || props.lineColor.from}, ${props.lineColor[100%] || props.lineColor.to}) } }) // 进度圈渐变色 id const circleGradient computed(() { if (isGradientColor.value) { const gradientColor props.lineColor as Gradient if (gradientColor.direction undefined || gradientColor.direction right) { return right-${gradientColor[0%] || gradientColor.from}-${gradientColor[100%] || gradientColor.to} } return left-${gradientColor[100%] || gradientColor.to}-${gradientColor[0%] || gradientColor.from} } return null }) const circleColorFrom computed(() { if (isGradientColor.value) { const gradientColor props.lineColor as Gradient if (gradientColor.direction undefined || gradientColor.direction right) { return gradientColor[0%] || gradientColor.from } else { return gradientColor[100%] || gradientColor.to } } return }) const circleColorTo computed(() { if (isGradientColor.value) { const gradientColor props.lineColor as Gradient if (!gradientColor.direction || gradientColor.direction right) { return gradientColor[100%] || gradientColor.to } else { return gradientColor[0%] || gradientColor.from } } return }) const showPercent computed(() { return props.format(props.percent 100 ? 100 : props.percent) }) const showSuccess computed(() { return slotsExist.success || props.success }) /script template div v-iftype line classprogress-line-wrap :style --progress-size: ${progressSize}; --progress-primary-color: ${lineColorComputed}; --progress-success-color: #52c41a; --progress-font-size: ${progressInfoSize}; --progress-border-radius: ${lineCap round ? 100px : 0}; div classprogress-inner div :class[progress-bg, { line-success: percent 100 !isGradientColor }] :stylewidth: ${percent 100 ? 100 : percent}%; height: ${progressLineSize}px; /div /div template v-ifshowInfo Transition namefade modeout-in span v-ifpercent 100 classprogress-success svg v-ifshowSuccess undefined classicon-svg focusablefalse >script setup langts import Progress from ./Progress.vue import { ref } from vue import { MinusOutlined, PlusOutlined } from ant-design/icons-vue import type { ProgressProps } from vue-amazing-ui const percent ref(80) const lineCapOptions [ { label: round, value: round }, { label: butt, value: butt } ] const lineCap refProgressProps[lineCap](butt) function onIncrease(scale: number) { const res percent.value scale if (res 100) { percent.value 100 } else { percent.value res } } function onDecline(scale: number) { const res percent.value - scale if (res 0) { percent.value 0 } else { percent.value res } } /script template div stylewidth: 900px h1{{ $route.name }} {{ $route.meta.title }}/h1 h2 classmt30 mb10基本使用/h2 Progress :percentpercent / h2 classmt30 mb10进度圈/h2 Space aligncenter Progress typecircle :percentpercent / Button clickonDecline(5) sizelarge :iconMinusOutlinedDecline/Button Button clickonIncrease(5) sizelarge :iconPlusOutlinedIncrease/Button /Space h2 classmt30 mb10完成进度条/h2 Flex vertical Progress :percent100 / Progress typecircle :percent100 / /Flex h2 classmt30渐变进度条/h2 h3 classmb10 strokeColor: { 0%: #108ee9, 100%: #87d068, direction: right } 或 { from: #108ee9, to: #87d068, direction: right } /h3 Flex vertical Progress :line-color{ 0%: #108ee9, 100%: #87d068 } :percentpercent / Space aligncenter Progress typecircle :line-color{ 0%: #108ee9, 100%: #87d068 } :percentpercent / Button clickonDecline(5) sizelarge :iconMinusOutlinedDecline/Button Button clickonIncrease(5) sizelarge :iconPlusOutlinedIncrease/Button /Space /Flex h2 classmt30 mb10自定义样式/h2 Flex vertical Progress style--progress-success-color: #ff6900 :line-size24 :line-color{ 0%: #108ee9, 100%: #87d068, direction: left } :info-size24 :percentpercent / Space aligncenter Progress style--progress-success-color: #ff6900 typecircle :width180 :line-size14 :line-color{ 0%: #108ee9, 100%: #87d068, direction: left } :info-size28 :percentpercent / Button clickonDecline(5) sizelarge :iconMinusOutlinedDecline/Button Button clickonIncrease(5) sizelarge :iconPlusOutlinedIncrease/Button /Space /Flex h2 classmt30 mb10自定义边缘形状/h2 Flex vertical Radio :optionslineCapOptions v-model:valuelineCap button button-stylesolid / Progress :line-size20 :line-color{ 0%: white, 100%: pink } :line-caplineCap :info-size20 :percentpercent / Space aligncenter Progress typecircle :width160 :line-size12 :line-color{ 0%: #e3f2fd, 100%: #2080f0 } :line-caplineCap :info-size24 :percentpercent / Button clickonDecline(5) sizelarge :iconMinusOutlinedDecline/Button Button clickonIncrease(5) sizelarge :iconPlusOutlinedIncrease/Button /Space /Flex h2 classmt30 mb10自定义文字/h2 Flex vertical Progress :line-size20 :info-size20 :percentpercent :format(percent: number) $${percent} successDone / Progress style--success-color: #d48806 :line-size20 :info-size20 :percentpercent template #format{ percent } span stylecolor: #d4380d{{ percent }}%/span /template template #success span stylecolor: #d48806Bingo/span /template /Progress Space aligncenter Progress typecircle :width160 :line-size12 :info-size24 :percentpercent :format(percent: number) ${percent} Days successDone / Progress style--success-color: #d48806 typecircle :width160 :line-size12 :info-size24 :percentpercent template #format{ percent } span stylecolor: #d4380d{{ percent }}%/span /template template #success span stylecolor: #d48806Bingo/span /template /Progress Button clickonDecline(5) sizelarge :iconMinusOutlinedDecline/Button Button clickonIncrease(5) sizelarge :iconPlusOutlinedIncrease/Button /Space /Flex /div /template