mirror of
https://gitee.com/wot-design-uni/wot-design-uni.git
synced 2025-12-06 17:18:40 +08:00
parent
7bc359205d
commit
c136f54cda
@ -1,12 +1,9 @@
|
|||||||
<frame/>
|
<frame/>
|
||||||
|
|
||||||
# Progress 进度条
|
# Progress 进度条
|
||||||
|
|
||||||
|
|
||||||
用于展示操作的当前进度。
|
用于展示操作的当前进度。
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## 基本用法
|
## 基本用法
|
||||||
|
|
||||||
设置百分比 `percentage`。
|
设置百分比 `percentage`。
|
||||||
@ -20,7 +17,7 @@
|
|||||||
设置 `hide-text` 隐藏进度文字。
|
设置 `hide-text` 隐藏进度文字。
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<wd-progress :percentage="60" hide-text>
|
<wd-progress :percentage="60" hide-text></wd-progress>
|
||||||
```
|
```
|
||||||
|
|
||||||
## 设置状态
|
## 设置状态
|
||||||
@ -37,7 +34,7 @@
|
|||||||
设置 `color` 修改进度条颜色。
|
设置 `color` 修改进度条颜色。
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<wd-progress :percentage="80" color="#00c740">
|
<wd-progress :percentage="80" color="#00c740"></wd-progress>
|
||||||
```
|
```
|
||||||
|
|
||||||
`color` 也可以设置为数组或者函数。数组如果只传入颜色,则自动计算每个颜色的进度边界。函数需要返回一个颜色值。
|
`color` 也可以设置为数组或者函数。数组如果只传入颜色,则自动计算每个颜色的进度边界。函数需要返回一个颜色值。
|
||||||
@ -49,11 +46,13 @@
|
|||||||
数组也可以设置为以下格式:
|
数组也可以设置为以下格式:
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<wd-progress :percentage="percentage" :color="colorObject"/>
|
<wd-progress :percentage="percentage" :color="colorObject" />
|
||||||
```
|
```
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
const colorObject = ref<any>([
|
import type { ProgressColor } from '@/uni_modules/wot-design-uni/components/wd-progress/types'
|
||||||
|
|
||||||
|
const colorObject = ref<ProgressColor>([
|
||||||
{
|
{
|
||||||
color: 'yellow',
|
color: 'yellow',
|
||||||
percentage: 30
|
percentage: 30
|
||||||
@ -76,17 +75,23 @@ const percentage = ref<number>(100)
|
|||||||
|
|
||||||
## Attributes
|
## Attributes
|
||||||
|
|
||||||
| 参数 | 说明 | 类型 | 可选值 | 默认值 | 最低版本 |
|
| 参数 | 说明 | 类型 | 可选值 | 默认值 | 最低版本 |
|
||||||
|-----|-----|------|-------|-------|--------|
|
| ---------- | --------------------- | --------------------------------------- | ---------------- | ------ | -------- |
|
||||||
| percentage | 进度数值,最大值100 | number | - | 0 | - |
|
| percentage | 进度数值,最大值 100 | `number` | - | 0 | - |
|
||||||
| hide-text | 隐藏进度文字 | boolean | - | false | - |
|
| hide-text | 隐藏进度文字 | `boolean` | - | false | - |
|
||||||
| color | 进度条颜色 | string / array | - | linear-gradient(315deg, rgba(81,124,240,1) 0%,rgba(118,158,245,1) 100%) | - |
|
| color | 进度条颜色 | `string \| ProgressColor[] \| string[]` | - | - | - |
|
||||||
| status | 进度条状态 | string | success / danger | - | - |
|
| status | 进度条状态 | `string` | success \| danger \| warning | - | - |
|
||||||
| duration | 进度增加1%所需毫秒数 | number | - | 30 | - |
|
| duration | 进度增加 1%所需毫秒数 | `number` | - | 30 | - |
|
||||||
|
|
||||||
|
### ProgressColor
|
||||||
|
|
||||||
|
| 字段 | 说明 | 说明 | 最低版本 |
|
||||||
|
| ---------- | ------ | ------ | -------- |
|
||||||
|
| color | string | 颜色 | - |
|
||||||
|
| percentage | number | 百分比 | - |
|
||||||
|
|
||||||
## 外部样式类
|
## 外部样式类
|
||||||
|
|
||||||
| 类名 | 说明 | 最低版本 |
|
| 类名 | 说明 | 最低版本 |
|
||||||
|-----|------|--------|
|
| ------------ | ---------- | -------- |
|
||||||
| custom-class | 根节点样式 | - |
|
| custom-class | 根节点样式 | - |
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<page-wraper>
|
<page-wraper>
|
||||||
<demo-block title="基本用法">
|
<demo-block title="基本用法">
|
||||||
<wd-progress :percentage="30" />
|
<wd-progress :percentage="percentageZero" />
|
||||||
</demo-block>
|
</demo-block>
|
||||||
|
|
||||||
<demo-block title="不显示进度文字">
|
<demo-block title="不显示进度文字">
|
||||||
@ -11,6 +11,7 @@
|
|||||||
<demo-block title="进度条状态">
|
<demo-block title="进度条状态">
|
||||||
<wd-progress :percentage="100" hide-text status="success" />
|
<wd-progress :percentage="100" hide-text status="success" />
|
||||||
<wd-progress :percentage="80" hide-text status="danger" />
|
<wd-progress :percentage="80" hide-text status="danger" />
|
||||||
|
<wd-progress :percentage="90" hide-text status="warning" />
|
||||||
</demo-block>
|
</demo-block>
|
||||||
|
|
||||||
<demo-block title="修改颜色">
|
<demo-block title="修改颜色">
|
||||||
@ -21,12 +22,35 @@
|
|||||||
<wd-progress :percentage="100" :color="['#00c740', '#ffb300', '#e2231a', '#0083ff']" />
|
<wd-progress :percentage="100" :color="['#00c740', '#ffb300', '#e2231a', '#0083ff']" />
|
||||||
<wd-progress :percentage="percentage" :color="colorObject" />
|
<wd-progress :percentage="percentage" :color="colorObject" />
|
||||||
</demo-block>
|
</demo-block>
|
||||||
|
|
||||||
|
<demo-block title="动态设置">
|
||||||
|
<wd-progress :percentage="percentageDynamic" />
|
||||||
|
<wd-button custom-style="margin-right: 10px;" @click="add" type="success" size="small">+10</wd-button>
|
||||||
|
<wd-button @click="reduce" type="error" size="small">-10</wd-button>
|
||||||
|
</demo-block>
|
||||||
</page-wraper>
|
</page-wraper>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
import type { ProgressColor } from '@/uni_modules/wot-design-uni/components/wd-progress/types'
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
|
|
||||||
const colorObject = ref<any>([
|
const percentageZero = ref<number>(30)
|
||||||
|
const percentage = ref<number>(100)
|
||||||
|
|
||||||
|
// 动态进度 变量
|
||||||
|
const percentageDynamic = ref<number>(50)
|
||||||
|
|
||||||
|
// 动态变量加10
|
||||||
|
const add = () => {
|
||||||
|
percentageDynamic.value = Math.min(percentageDynamic.value + 10, 100)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 动态变量减10
|
||||||
|
const reduce = () => {
|
||||||
|
percentageDynamic.value = Math.max(percentageDynamic.value - 10, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
const colorObject = ref<ProgressColor[]>([
|
||||||
{
|
{
|
||||||
color: 'yellow',
|
color: 'yellow',
|
||||||
percentage: 30
|
percentage: 30
|
||||||
@ -44,6 +68,5 @@ const colorObject = ref<any>([
|
|||||||
percentage: 90
|
percentage: 90
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
const percentage = ref<number>(100)
|
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped></style>
|
<style lang="scss" scoped></style>
|
||||||
|
|||||||
@ -486,15 +486,9 @@ $-progress-padding: var(--wot-progress-padding, 9px 0 8px) !default; // 进度
|
|||||||
$-progress-bg: var(--wot-progress-bg, rgba(229, 229, 229, 1)) !default; // 进度条底色
|
$-progress-bg: var(--wot-progress-bg, rgba(229, 229, 229, 1)) !default; // 进度条底色
|
||||||
$-progress-danger-color: var(--wot-progress-danger-color, $-color-danger) !default; // 进度条danger颜色
|
$-progress-danger-color: var(--wot-progress-danger-color, $-color-danger) !default; // 进度条danger颜色
|
||||||
$-progress-success-color: var(--wot-progress-success-color, $-color-success) !default; // 进度条success进度条颜色
|
$-progress-success-color: var(--wot-progress-success-color, $-color-success) !default; // 进度条success进度条颜色
|
||||||
$-progress-color: var(--wot-progress-color, resultColor(315deg, $-color-theme, 'dark' 'light', #517cf0 #769ef5, 0% 100%)) !default; // 进度条渐变色
|
$-progress-warning-color: var(--wot-progress-warning-color, $-color-warning) !default; // 进度条warning进度条颜色
|
||||||
$-progress-linear-success-color: var(
|
|
||||||
--wot-progress-linear-success-color,
|
$-progress-color: var(--wot-progress-color, $-color-theme) !default; // 进度条颜色
|
||||||
resultColor(315deg, $-color-theme, 'dark' 'light', #20b080 #2bd69d, 0% 100%)
|
|
||||||
) !default; // success进度条渐变色
|
|
||||||
$-progress-linear-danger-color: var(
|
|
||||||
--wot-progress-linear-danger-color,
|
|
||||||
resultColor(315deg, $-color-theme, 'dark' 'light', #e04350 #ff5964, 0% 100%)
|
|
||||||
) !default; // danger进度条渐变色
|
|
||||||
$-progress-height: var(--wot-progress-height, 3px) !default; // 进度条高度
|
$-progress-height: var(--wot-progress-height, 3px) !default; // 进度条高度
|
||||||
$-progress-label-color: var(--wot-progress-label-color, #333) !default; // 文字颜色
|
$-progress-label-color: var(--wot-progress-label-color, #333) !default; // 文字颜色
|
||||||
$-progress-label-fs: var(--wot-progress-label-fs, 14px) !default; // 文字字号
|
$-progress-label-fs: var(--wot-progress-label-fs, 14px) !default; // 文字字号
|
||||||
|
|||||||
@ -37,10 +37,13 @@
|
|||||||
font-size: $-progress-icon-fs;
|
font-size: $-progress-icon-fs;
|
||||||
|
|
||||||
@include when(danger) {
|
@include when(danger) {
|
||||||
background: $-progress-linear-danger-color;
|
background: $-progress-danger-color;
|
||||||
}
|
}
|
||||||
@include when(success) {
|
@include when(success) {
|
||||||
background: $-progress-linear-success-color;
|
background: $-progress-success-color;
|
||||||
|
}
|
||||||
|
@include when(warning) {
|
||||||
|
background: $-progress-warning-color;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@include edeep(label) {
|
@include edeep(label) {
|
||||||
@ -58,5 +61,8 @@
|
|||||||
@include when(success) {
|
@include when(success) {
|
||||||
color: $-progress-success-color;
|
color: $-progress-success-color;
|
||||||
}
|
}
|
||||||
|
@include when(warning) {
|
||||||
|
color: $-progress-warning-color;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,16 +1,21 @@
|
|||||||
/*
|
/*
|
||||||
* @Author: weisheng
|
* @Author: weisheng
|
||||||
* @Date: 2024-03-15 20:40:34
|
* @Date: 2024-03-15 20:40:34
|
||||||
* @LastEditTime: 2024-03-18 15:32:11
|
* @LastEditTime: 2024-11-30 00:01:23
|
||||||
* @LastEditors: weisheng
|
* @LastEditors: weisheng
|
||||||
* @Description:
|
* @Description:
|
||||||
* @FilePath: \wot-design-uni\src\uni_modules\wot-design-uni\components\wd-progress\types.ts
|
* @FilePath: /wot-design-uni/src/uni_modules/wot-design-uni/components/wd-progress/types.ts
|
||||||
* 记得注释
|
* 记得注释
|
||||||
*/
|
*/
|
||||||
import type { PropType } from 'vue'
|
import type { PropType } from 'vue'
|
||||||
import { baseProps, makeBooleanProp, makeNumberProp } from '../common/props'
|
import { baseProps, makeBooleanProp, makeNumberProp } from '../common/props'
|
||||||
|
|
||||||
export type ProgressStatus = 'success' | 'danger' // 状态类型
|
export type ProgressStatus = 'success' | 'danger' | 'warning' // 状态类型
|
||||||
|
|
||||||
|
export type ProgressColor = {
|
||||||
|
color: string // 颜色
|
||||||
|
percentage: number // 百分比
|
||||||
|
}
|
||||||
|
|
||||||
export const progressProps = {
|
export const progressProps = {
|
||||||
...baseProps,
|
...baseProps,
|
||||||
@ -26,8 +31,7 @@ export const progressProps = {
|
|||||||
* 进度条颜色
|
* 进度条颜色
|
||||||
*/
|
*/
|
||||||
color: {
|
color: {
|
||||||
type: [String, Array, Object] as PropType<string | string[] | Record<string, any>[]>,
|
type: [String, Array] as PropType<string | string[] | ProgressColor[]>
|
||||||
default: 'linear-gradient(315deg, rgba(81,124,240,1) 0%,rgba(118,158,245,1) 100%)'
|
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* 进度增加1%所需毫秒数
|
* 进度增加1%所需毫秒数
|
||||||
|
|||||||
@ -1,15 +1,13 @@
|
|||||||
<template>
|
<template>
|
||||||
<view :class="`wd-progress ${customClass}`" :style="customStyle">
|
<view :class="`wd-progress ${customClass}`" :style="customStyle">
|
||||||
<!--进度条-->
|
|
||||||
<view class="wd-progress__outer">
|
<view class="wd-progress__outer">
|
||||||
<view :class="`wd-progress__inner ${progressClass}`" :style="rootStyle"></view>
|
<view :class="`wd-progress__inner ${innerClass}`" :style="rootStyle"></view>
|
||||||
</view>
|
</view>
|
||||||
<!--文案、图标-->
|
|
||||||
<view v-if="!hideText" class="wd-progress__label">{{ percentage }}%</view>
|
<view v-if="!hideText" class="wd-progress__label">{{ percentage }}%</view>
|
||||||
<wd-icon
|
<wd-icon
|
||||||
v-else-if="status"
|
v-else-if="status"
|
||||||
:custom-class="`wd-progress__label wd-progress__icon ${progressClass}`"
|
:custom-class="`wd-progress__label wd-progress__icon ${innerClass}`"
|
||||||
:name="status == 'danger' ? 'close-outline' : 'check-outline'"
|
:name="iconName"
|
||||||
:color="typeof color === 'string' ? color : ''"
|
:color="typeof color === 'string' ? color : ''"
|
||||||
></wd-icon>
|
></wd-icon>
|
||||||
</view>
|
</view>
|
||||||
@ -29,163 +27,171 @@ export default {
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import wdIcon from '../wd-icon/wd-icon.vue'
|
import wdIcon from '../wd-icon/wd-icon.vue'
|
||||||
import { computed, ref, watch } from 'vue'
|
import { computed, ref, watch } from 'vue'
|
||||||
import { checkNumRange, isArray, objToStyle } from '../common/util'
|
import { isArray, isDef, isObj, objToStyle, pause } from '../common/util'
|
||||||
import { progressProps } from './types'
|
import { progressProps, type ProgressColor } from './types'
|
||||||
|
|
||||||
const props = defineProps(progressProps)
|
const props = defineProps(progressProps)
|
||||||
// 进度条展示的颜色
|
|
||||||
const showColor = ref<string>('')
|
const showColor = ref<string>('')
|
||||||
// 进度条展示的进度
|
|
||||||
const showPercent = ref<number>(0)
|
const showPercent = ref<number>(0)
|
||||||
// newPercent - oldPercent 的绝对值
|
|
||||||
const changeCount = ref<number>(0)
|
const changeCount = ref<number>(0)
|
||||||
const progressClass = ref<string>('')
|
let timer: NodeJS.Timeout | null = null
|
||||||
|
|
||||||
let timer: NodeJS.Timeout | null = null // 定时器
|
|
||||||
|
|
||||||
const rootStyle = computed(() => {
|
const rootStyle = computed(() => {
|
||||||
const style: Record<string, string | number> = {
|
return objToStyle({
|
||||||
background: showColor.value,
|
background: showColor.value,
|
||||||
width: showPercent.value + '%',
|
width: `${showPercent.value}%`,
|
||||||
'transition-duration': changeCount.value * props.duration * 0.001 + 's'
|
'transition-duration': `${changeCount.value * props.duration * 0.001}s`
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
const innerClass = computed(() => (props.status ? `is-${props.status}` : ''))
|
||||||
|
|
||||||
|
const iconName = computed(() => {
|
||||||
|
let icon: string = ''
|
||||||
|
switch (props.status) {
|
||||||
|
case 'danger':
|
||||||
|
icon = 'close-outline'
|
||||||
|
break
|
||||||
|
case 'success':
|
||||||
|
icon = 'check-outline'
|
||||||
|
break
|
||||||
|
case 'warning':
|
||||||
|
icon = 'warn-bold'
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
break
|
||||||
}
|
}
|
||||||
return objToStyle(style)
|
return icon
|
||||||
})
|
})
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => props.percentage,
|
() => [props.percentage, props.color, props.duration],
|
||||||
(newValue) => {
|
|
||||||
// 校验类型
|
|
||||||
if (Number.isNaN(newValue) || newValue < 0 || newValue > 100) {
|
|
||||||
console.error('The value of percentage must be between 0 and 100')
|
|
||||||
}
|
|
||||||
controlProgress()
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
watch(
|
|
||||||
() => props.color,
|
|
||||||
() => {
|
() => {
|
||||||
controlProgress()
|
validatePercentage(props.percentage)
|
||||||
|
updateProgress()
|
||||||
},
|
},
|
||||||
{
|
{ immediate: true }
|
||||||
deep: true,
|
|
||||||
immediate: true
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
watch(
|
function validatePercentage(value: number) {
|
||||||
() => props.status,
|
if (Number.isNaN(value) || value < 0 || value > 100) {
|
||||||
() => {
|
console.error('The value of percentage must be between 0 and 100')
|
||||||
computeProgressClass()
|
|
||||||
},
|
|
||||||
{
|
|
||||||
deep: true,
|
|
||||||
immediate: true
|
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
|
||||||
watch(
|
|
||||||
() => props.duration,
|
|
||||||
(newValue) => {
|
|
||||||
checkNumRange(newValue)
|
|
||||||
},
|
|
||||||
{
|
|
||||||
deep: true,
|
|
||||||
immediate: true
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
function computeProgressClass() {
|
|
||||||
const { status } = props
|
|
||||||
let progressClasses: string[] = []
|
|
||||||
status && progressClasses.push(`is-${status}`)
|
|
||||||
progressClass.value = progressClasses.join(' ')
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description
|
* 进度条前进
|
||||||
* @param {Number} targetPercent 目标值
|
* @param partList 颜色数组
|
||||||
* @param {String} color 目标颜色
|
* @param percentage 进度值
|
||||||
*/
|
*/
|
||||||
|
function updateProgressForward(partList: ProgressColor[], percentage: number) {
|
||||||
|
return partList.some((part, index) => {
|
||||||
|
if (showPercent.value < part.percentage && part.percentage <= percentage) {
|
||||||
|
update(part.percentage, part.color)
|
||||||
|
return true
|
||||||
|
} else if (index === partList.length - 1) {
|
||||||
|
update(percentage, part.color)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 进度条后退
|
||||||
|
* @param partList 颜色数组
|
||||||
|
* @param percentage 进度值
|
||||||
|
*/
|
||||||
|
function updateProgressBackward(partList: ProgressColor[], percentage: number) {
|
||||||
|
return partList.some((part) => {
|
||||||
|
if (percentage <= part.percentage) {
|
||||||
|
update(percentage, part.color)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新进度条
|
||||||
|
*/
|
||||||
|
async function updateProgress() {
|
||||||
|
const { percentage, color } = props
|
||||||
|
if (!isDef(color) || (isArray(color) && color.length === 0)) {
|
||||||
|
changeCount.value = Math.abs(percentage - showPercent.value)
|
||||||
|
await pause()
|
||||||
|
showPercent.value = percentage
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (showPercent.value === percentage) return
|
||||||
|
|
||||||
|
const colorArray = isArray(color) ? color : [color]
|
||||||
|
validateColorArray(colorArray)
|
||||||
|
const partList = createPartList(colorArray)
|
||||||
|
showPercent.value > percentage ? updateProgressBackward(partList, percentage) : updateProgressForward(partList, percentage)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断是否是颜色数组
|
||||||
|
* @param array 颜色数组
|
||||||
|
*/
|
||||||
|
function isProgressColorArray(array: string[] | ProgressColor[]): array is ProgressColor[] {
|
||||||
|
return array.every(
|
||||||
|
(color) => isObj(color) && Object.prototype.hasOwnProperty.call(color, 'color') && Object.prototype.hasOwnProperty.call(color, 'percentage')
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断是否是字符串数组
|
||||||
|
* @param array 颜色数组
|
||||||
|
*/
|
||||||
|
function isStringArray(array: string[] | ProgressColor[]): array is string[] {
|
||||||
|
return array.every((item) => typeof item === 'string')
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 颜色数组校验
|
||||||
|
* @param colorArray 颜色数组
|
||||||
|
*/
|
||||||
|
function validateColorArray(colorArray: string[] | ProgressColor[]) {
|
||||||
|
const isStrArray = isStringArray(colorArray)
|
||||||
|
const isObjArray = isProgressColorArray(colorArray)
|
||||||
|
if (!isStrArray && !isObjArray) {
|
||||||
|
throw Error('Color must be String or Object with color and percentage')
|
||||||
|
}
|
||||||
|
if (isObjArray && colorArray.some(({ percentage }) => Number.isNaN(percentage))) {
|
||||||
|
throw Error('All the percentage must can be formatted to Number')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建颜色数组
|
||||||
|
* @param colorArray 颜色数组
|
||||||
|
* @return 颜色数组
|
||||||
|
*/
|
||||||
|
function createPartList(colorArray: string[] | ProgressColor[]) {
|
||||||
|
const partNum = 100 / colorArray.length
|
||||||
|
return isProgressColorArray(colorArray)
|
||||||
|
? colorArray.sort((a, b) => a.percentage - b.percentage)
|
||||||
|
: colorArray.map((item, index) => ({
|
||||||
|
color: item,
|
||||||
|
percentage: (index + 1) * partNum
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
function update(targetPercent: number, color: string) {
|
function update(targetPercent: number, color: string) {
|
||||||
// 需要等上一个定时器跑完
|
|
||||||
if (timer) return
|
if (timer) return
|
||||||
const { duration } = props
|
const { duration } = props
|
||||||
// transition-duration的优先更高
|
|
||||||
changeCount.value = Math.abs(targetPercent - showPercent.value)
|
changeCount.value = Math.abs(targetPercent - showPercent.value)
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
showPercent.value = targetPercent
|
showPercent.value = targetPercent
|
||||||
showColor.value = color
|
showColor.value = color
|
||||||
timer = setTimeout(() => {
|
timer = setTimeout(() => {
|
||||||
clearTimeout(timer as any)
|
timer && clearTimeout(timer)
|
||||||
timer = null
|
timer = null
|
||||||
controlProgress()
|
updateProgress()
|
||||||
}, changeCount.value * duration)
|
}, changeCount.value * duration)
|
||||||
}, 50)
|
}, 50)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @description 控制进度条的进度和每段的颜色
|
|
||||||
*/
|
|
||||||
function controlProgress() {
|
|
||||||
const {
|
|
||||||
// 目标百分比
|
|
||||||
percentage,
|
|
||||||
// 传入的color数组
|
|
||||||
color
|
|
||||||
} = props
|
|
||||||
// 锁
|
|
||||||
if (showPercent.value === percentage || !percentage) return
|
|
||||||
/**
|
|
||||||
* 数组边界安全判断
|
|
||||||
*/
|
|
||||||
let colorArray: string[] | Record<string, any>[] = (isArray(color) ? color : [color]) as string[] | Record<string, any>[]
|
|
||||||
if (colorArray.length === 0) throw Error('The colorArray is empty')
|
|
||||||
const isStrArray = (colorArray as any).every((item: any) => typeof item === 'string')
|
|
||||||
// eslint-disable-next-line no-prototype-builtins
|
|
||||||
const isObjArray = (colorArray as any).every((color: any) => color.hasOwnProperty('color') && color.hasOwnProperty('percentage'))
|
|
||||||
if (!isStrArray && !isObjArray) {
|
|
||||||
throw Error('Color must be String or Object with color and percentage')
|
|
||||||
}
|
|
||||||
if (isObjArray && (colorArray as any).some(({ percentage }: any) => Number.isNaN(parseInt(percentage)))) {
|
|
||||||
throw Error('All the percentage must can be formatted to Number')
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* 根据colorArray平均分布每段color值,或使用用户自定义的值
|
|
||||||
*/
|
|
||||||
const partNum = parseInt(`${100 / colorArray.length}`)
|
|
||||||
const partList = isObjArray
|
|
||||||
? colorArray.sort((a: any, b: any) => a.percentage - b.percentage)
|
|
||||||
: colorArray.map((item, index) => {
|
|
||||||
return {
|
|
||||||
color: item,
|
|
||||||
percentage: (index + 1) * partNum
|
|
||||||
}
|
|
||||||
})
|
|
||||||
/**
|
|
||||||
* 找到当前目标
|
|
||||||
*/
|
|
||||||
showPercent.value > percentage
|
|
||||||
? // 减小不加动画,找到第一个比target大的锚点,取锚点颜色并设置target值
|
|
||||||
partList.some((part: any) => {
|
|
||||||
if (percentage <= part.percentage) {
|
|
||||||
update(percentage, part.color)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
})
|
|
||||||
: // 增加使用分段动画
|
|
||||||
partList.some((part: any, index: number) => {
|
|
||||||
if (showPercent.value < part.percentage && part.percentage <= percentage) {
|
|
||||||
// 找到第一个比now大的点,如果这个点比target小或等,就把这个点设置为下一个即将展示的点
|
|
||||||
update(part.percentage, part.color)
|
|
||||||
return true
|
|
||||||
} else if (index === partList.length - 1) {
|
|
||||||
update(percentage, part.color)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import './index.scss';
|
@import './index.scss';
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user