Files
smart-admin/smart_admin_v1/smart-admin-web/src/components/count-to/count-to.vue
2022-10-27 22:14:48 +08:00

199 lines
4.3 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="count-to-wrapper">
<slot name="left"/>
<p class="content-outer">
<span :class="['count-to-count-text', countClass]" :id="counterId">{{ init }}</span>
<i :class="['count-to-unit-text', unitClass]">{{ unitText }}</i>
</p>
<slot name="right"/>
</div>
</template>
<script>
import CountUp from 'countup';
import './index.less';
export default {
name: 'countTo',
props: {
/**
* @description 默认值
*/
init: {
type: Number,
required: false,
default: 0
},
/**
* @description 起始值,即动画开始前显示的数值
*/
startVal: {
type: Number,
required: false,
default: 0
},
/**
* @description 结束值,即动画结束后显示的数值
*/
end: {
type: Number,
required: true
},
/**
* @description 保留几位小数
*/
decimals: {
type: Number,
required: false,
default: 0
},
/**
* @description 分隔整数和小数的符号,默认是小数点
*/
decimal: {
type: String,
required: false,
default: '.'
},
/**
* @description 动画持续的时间,单位是秒
*/
duration: {
type: Number,
required: false,
default: 2
},
/**
* @description 动画延迟开始的时间,单位是秒
*/
delay: {
type: Number,
required: false,
default: 0
},
/**
* @description 是否禁用easing动画效果
*/
uneasing: {
type: Boolean,
required: false,
default: false
},
/**
* @description 是否使用分组,分组后每三位会用一个符号分隔
*/
usegroup: {
type: Boolean,
required: false,
default: false
},
/**
* @description 用于分组(usegroup)的符号
*/
separator: {
type: String,
required: false,
default: ','
},
/**
* @description 是否简化显示设为true后会使用unit单位来做相关省略
*/
simplify: {
type: Boolean,
required: false,
default: false
},
/**
* @description 自定义单位,如[3, 'K+'], [6, 'M+']即大于3位数小于6位数的用k+来做省略
* 1000即显示为1K+
*/
unit: {
type: Array,
required: false,
default () {
return [[3, 'K+'], [6, 'M+'], [9, 'B+']];
}
},
// 数值样式
countClass: {
type: String,
required: false,
default: ''
},
// 单位样式
unitClass: {
type: String,
required: false,
default: ''
}
},
data () {
return {
// CountUp 实例
counter: null,
// 单位描述
unitText: ''
};
},
computed: {
// 唯一标识
counterId () {
return `count_to_${this._uid}`;
}
},
watch: {
end (newVal) {
let endVal = this.getValue(newVal);
this.counter.update(endVal);
}
},
mounted () {
this.$nextTick(() => {
let endVal = this.getValue(this.end);
this.counter = new CountUp(this.counterId, this.startVal, endVal, this.decimals, this.duration, {
useEasing: !this.uneasing,
useGrouping: this.useGroup,
separator: this.separator,
decimal: this.decimal
});
setTimeout(() => {
if (!this.counter.error) this.counter.start();
}, this.delay);
});
},
methods: {
getHandleVal (val, len) {
return {
endVal: parseInt(val / Math.pow(10, this.unit[len - 1][0])),
unitText: this.unit[len - 1][1]
};
},
transformValue (val) {
let len = this.unit.length;
let res = {
endVal: 0,
unitText: ''
};
if (val < Math.pow(10, this.unit[0][0])) res.endVal = val;
else {
for (let i = 1; i < len; i++) {
if (val >= Math.pow(10, this.unit[i - 1][0]) && val < Math.pow(10, this.unit[i][0])) res = this.getHandleVal(val, i);
}
}
if (val > Math.pow(10, this.unit[len - 1][0])) res = this.getHandleVal(val, len);
return res;
},
getValue (val) {
let res = 0;
if (this.simplify) {
let { endVal, unitText } = this.transformValue(val);
this.unitText = unitText;
res = endVal;
} else {
res = val;
}
return res;
}
}
};
</script>