如题
<span>¥ <AnimatedMoney>{number || '0.00'}</AnimatedMoney></span>
import React, { Component } from 'react';
import PropTypes from 'prop-types';
export default class AnimatedMoney extends Component {
timeContainer = '';
index = 0;
static propTypes = {
dot: PropTypes.number, // 小数点位数
animated: PropTypes.bool, // 是否有动画
time: PropTypes.number, // 间隔时间
micrometer: PropTypes.bool, // 是否有千分符
children: PropTypes.number.isRequired
};
static defaultProps = {
dot: 2,
time: 20,
micrometer: true,
animated: true
};
constructor(props) {
super(props);
this.state = {
displayValue: 0
};
}
componentDidMount() {
this.init();
}
init = () => {
const { animated, micrometer, children } = this.props;
const numberVal = this.toNumber(children);
// 判断是否出现动画
if (!animated || numberVal === 0) {
let finalVal = children;
if (!micrometer) {
finalVal = this.deleteThousandSymbol(children);
}
this.setState({
displayValue: finalVal
});
return;
}
const valArr = this.getRandomArr(numberVal);
this.toSetInterval(valArr);
}
// 转成数字
toNumber = (value) => {
const { displayValue } = this.state;
let val = value;
if (val === undefined || val === null) {
return 0;
}
if (typeof val === 'string') {
if (this.isHaveThousandSymbol(value)) {
val = this.deleteThousandSymbol(val);
}
return Number(val);
} else if (typeof val === 'number') {
return val;
}
return displayValue;
}
toStrging = (value) => {
const { dot, micrometer } = this.props;
return value.toLocaleString('en-US', { minimumFractionDigits: dot, maximumFractionDigits: dot, useGrouping: micrometer });
}
// 是否有千分符
isHaveThousandSymbol = (val) => {
return val.toString().includes(',');
}
// 删除千分符
deleteThousandSymbol = (val) => {
return (val.toString().replace(/,/g, ''));
}
// 生成滚动数组
getRandomArr = (finalNumber) => {
const valArr = [];
let initVal = 0;
const step = finalNumber / 25;
for (let i = 0; i < 25; i += 1) {
initVal = step * i;
initVal = this.toStrging(initVal);
valArr.push(initVal);
}
valArr.push(this.toStrging(finalNumber));
return valArr;
}
// 设置定时器
toSetInterval = (valArr) => {
const { time } = this.props;
this.timeContainer = setInterval(() => {
this.setInnerData(valArr[this.index]);
this.index += 1;
if (this.index >= valArr.length) {
clearTimeout(this.timeContainer);
this.timeContainer = null;
}
}, time);
}
setInnerData = (val) => {
this.setState({
displayValue: val
});
}
render() {
const { displayValue } = this.state;
return (
<span>{displayValue}</span>
);
}
}