需求: TweenOne顯示數(shù)字組件當(dāng)數(shù)據(jù)太大的時(shí)候顯示數(shù)據(jù)不對,需要顯示正確數(shù)據(jù)迟几。
解決過程:
找到以下相關(guān)issue:
https://github.com/ant-design/ant-motion/issues/210
https://github.com/ant-design/ant-motion/issues/234
更新到最新版本后問題仍然存在消请,然后去查看了源代碼看到插件內(nèi)部沒有使用bignumber進(jìn)行處理,數(shù)據(jù)大的時(shí)候還是會(huì)有問題类腮,因此決定使用bignumber對這個(gè)插件進(jìn)行改動(dòng)使其支持bignumber梯啤,進(jìn)而滿足業(yè)務(wù)需求。
原因:
使用的插件
import Children from 'rc-tween-one/lib/plugin/ChildrenPlugin';
沒有使用bignumber進(jìn)行處理存哲。
解決方案:
修改這個(gè)插件使其滿足需要,修改前的代碼如下:
https://github.com/react-component/tween-one/blob/master/src/plugin/ChildrenPlugin.jsx
修改后的核心代碼如下:
ChildrenPlugin.prototype = {
setRatio(ratio) {
const { valueStr, floatLength, formatMoney } = this.vars;
let v ;
// = (value - this.start.value) * ratio + this.start.value;
v = new BigNumber(valueStr).minus(this.start.value).multipliedBy(ratio).plus(this.start.value);
if (typeof floatLength === 'number') {
if (floatLength) {
v = YData.removeTail0(v.toFixed(floatLength));//刪除尾部無效的0
} else {
v = v.toFixed(0);
}
}
v = formatMoney ? this.toMoney(v, formatMoney) : v;
this.target.innerHTML = v;
},
};
添加了字段:valueStr將字符串傳到AnimateNumber
import React from 'react';
import TweenOne from 'rc-tween-one';
// import Children from 'rc-tween-one/lib/plugin/ChildrenPlugin';
import config from 'utils/config';
import YData from 'appRoot/utils/YData';
import BigNumber from 'bignumber.js';
const ChildrenPlugin = function (target, vars) {
this.target = target;
this.vars = vars;
};
ChildrenPlugin.prototype = {
name: 'Children',
getAnimStart() {
const { formatMoney } = this.vars;
const opts = {
thousand: formatMoney && formatMoney.thousand || ',',
decimal: formatMoney && formatMoney.decimal || '.',
};
const rep = new RegExp(`\\${opts.thousand}`, 'g');
this.start = this.vars.startAt || {
value: parseFloat(this.target.innerHTML.replace(rep, '').replace(opts.decimal, '.')) || 0
};
},
toMoney(v, _opts) {
const opts = {
thousand: _opts.thousand || ',',
decimal: _opts.decimal || '.',
};
const negative = parseFloat(v) < 0 ? '-' : '';
const numberArray = v.toString().split('.');
const base = Math.abs(parseInt(numberArray[0], 10)).toString();
const mod = base.length > 3 ? base.length % 3 : 0;
const decimal = numberArray[1];
return `${negative}${mod ? `${base.substr(0, mod)}${opts.thousand}` : ''}${
base.substr(mod).replace(/(\d{3})(?=\d)/g, `$1${opts.thousand}`)}${
decimal ? `${opts.decimal}${decimal}` : ''
}`;
},
setRatio(ratio) {
const { valueStr, floatLength, formatMoney } = this.vars;
let v ;
// = (value - this.start.value) * ratio + this.start.value;
v = new BigNumber(valueStr).minus(this.start.value).multipliedBy(ratio).plus(this.start.value);
const vString = v.toString();
console.log('vString',vString)
if (typeof floatLength === 'number') {
if (floatLength) {
v = YData.removeTail0(v.toFixed(floatLength));//刪除尾部無效的0
} else {
v = v.toFixed(0);
}
}
v = formatMoney ? this.toMoney(v, formatMoney) : v;
this.target.innerHTML = v;
},
};
const Children = ChildrenPlugin;
TweenOne.plugins.push(Children);
/**
* 使 TweenOne 支持bignumber顯示七婴,添加了plugin Children 字段 valueStr
* <AnimateNumber
valueStr={valueStr} //valueStr = '1234567890123456789.1234567899';
value={Number(valueStr)}
floatLength={2}
/>
*
* @param {*} props
*/
const AnimateNumber = (props) => {
const { value, valueStr, formatMoney = true, floatLength = config.MAX_DECIMAL_DIGITS, duration = 1000, style } = props;
const animation = value || value === 0 ? {
Children: {
value: Number(valueStr),
valueStr: `${valueStr}`,
floatLength,
formatMoney,
},
duration,
} : null;
return (
<TweenOne
animation={animation}
style={style}
>
0
</TweenOne>
);
};
export default AnimateNumber;
參考:
https://motion.ant.design/components/tween-one#components-tween-one-demo-easingPath