文章目录
- 前言
- Decimal组件
-
- [1. 功能分析](#1. 功能分析)
- [2. 代码+详细注释](#2. 代码+详细注释)
- [3. 使用方式](#3. 使用方式)
- [4. 效果展示](#4. 效果展示)
- 总结
前言
今天要封装的Decimal 组件,是通过传入的属性进行定制化显示数值,在渲染时,会根据不同的情况显示整数部分、小数部分和单位,支持自定义样式、布局和单位,同时根据数值正负情况显示不同样式,适用于准确展示各种类型的数值数据。
Decimal组件
1. 功能分析
(1)支持不同的样式(type显示类型,layout布局类型)
(2)支持是否显示小数点后全部小数部分或默认8位小数(display属性)
(3)支持显示不同的单位(unit属性)
(4)结合type属性,判断是否根据数值的正负情况显示不同的样式
(5)使用useMemo,避免重复计算,并且使用 BigNumber 来进行精确的数值计算操作
(6)支持传入 className 自定义类名来修改样式
2. 代码+详细注释
c
// @/components/Decimal/index.tsx
import { useMemo, FC } from "react";
import BigNumber from "bignumber.js";
import classNames from "classnames";
import { DecimalContainer } from "./styled";
// 组件的属性类型
type Props = {
value: string; // 要显示的数值
type?: "value" | "compare"; // 显示类型,默认为 "value",当需要显示正负值,并且有颜色区分时,使用compare
layout?: "responsive" | "fixed"; // 布局类型,默认为 "fixed",响应式为responsive
unit?: "CKB" | string | null; // 显示的单位,默认为 "CKB"
display?: "full" | "short"; // 显示样式,默认为 "short",显示小数点后8位,为full时显示全部小数部分
className?: string; // 自定义的类名
};
const Decimal: FC<Props> = (props) => {
// 解构属性
const { value, type = "value", layout = "fixed", unit = "CKB", display = "short", className } = props;
// 使用 useMemo 缓存计算结果,避免重复计算
const [int, dec, status] = useMemo(() => {
const c = new BigNumber(value);
// 将数值格式化为字符串,并分割成整数部分和小数部分
const [int, dec] = c.toFormat(display === "short" ? 8 : undefined).split(".");
// 如果是比较模式,并且数值不为零,则返回整数部分和小数部分以及数值的正负
if (type !== "compare" || c.isZero()) return [int, dec];
if (c.isPositive()) return [int, dec, "positive"];
return [int, dec, "negative"];
}, [value, display, type]);
return (
<DecimalContainer className={classNames(className)} data-type={type} data-value-status={status} data-layout={layout}>
<span className={classNames("int")}>{int}</span>
{dec && <span className={classNames("dec monospace")}>{`.${dec}`}</span>}
{unit && <span className={`unit monospace`}>{unit}</span>}
</DecimalContainer>
);
};
export default Decimal;
------------------------------------------------------------------------------
// @/components/Decimal/styled.tsx
import styled from "styled-components";
import variables from "@/styles/variables.module.scss";
export const DecimalContainer = styled.div`
display: inline-flex;
align-items: flex-end;
font-size: 16px;
white-space: nowrap;
span.dec {
font-size: 12px;
}
.unit {
margin-left: 5px;
}
&[data-type="value"] {
span.dec {
color: var(--cd-gray-light-3);
}
}
&[data-type="compare"] {
color: var(--cd-gray-light-3);
&[data-value-status="positive"] {
color: var(--cd-primary-color);
&::before {
content: "+";
}
}
&[data-value-status="negative"] {
color: var(--cd-danger-color);
}
}
&[data-layout="responsive"] {
@media (max-width: ${variables.mobileBreakPoint}) {
font-size: 12px;
span.dec {
font-size: 10px;
}
.unit {
font-size: 12px;
}
}
}
`;
3. 使用方式
c
// 引入组件
import Decimal from '@/components/Decimal'
// 使用
{/* PC端、正数 */}
<Decimal value="888888.00000066666666666600" type="compare" />
{/* PC端、负数 */}
<Decimal value="-888888.00000066666666666600" type="compare" />
{/* PC端、显示所有小数点 */}
<Decimal value="888888.00000066666666666600" display="full" />
{/* 移动端尺寸 */}
<Decimal layout="responsive" value="888888.00000066666666666600" type="compare" />
4. 效果展示
总结
下一篇讲【全局常用组件Echarts封装】。关注本栏目,将实时更新。