sanitize —— 数值净化
页码、间距、step、precision、尺寸上限——core 层大量函数接收外部数值。NaN / Infinity 一旦流入会一路污染下游:NaNpx 的样式、slice(NaN) 的空数组、toFixed(1000) 的 RangeError 崩渲染。这个模块的策略是在入口统一拦截,下游算法只处理「已经干净」的数。
import { sanitizeNumber, clamp, safePrecision, LH_PRECISION_MAX, type LhSanitizeNumberOptions,} from '@lh-ui/share/core/shared/sanitize'export interface LhSanitizeNumberOptions { min?: number // 允许的最小值(非有限的 min 自身被忽略) max?: number // 允许的最大值(非有限的 max 自身被忽略) integer?: boolean // 是否取整(向 0 截断)}
export const LH_PRECISION_MAX = 100 // precision 上限:toFixed 超过 100 位会抛 RangeError| 函数 | 签名 | 作用 |
|---|---|---|
sanitizeNumber |
(value: number | undefined | null, fallback: number, options?) => number |
把任意数值净化为有限数 |
clamp |
(value: number, min: number, max: number) => number |
原始钳制,不做任何净化 |
safePrecision |
(precision: number) => number |
precision 净化为 [0, 100] 整数 |
sanitizeNumber
Section titled “sanitizeNumber”sanitizeNumber(5, 0) // 5sanitizeNumber(NaN, 0) // 0sanitizeNumber(Infinity, 10) // 10sanitizeNumber(undefined, 1) // 1sanitizeNumber(null, 1) // 1sanitizeNumber(3.7, 0, { integer: true }) // 3(向 0 截断,非四舍五入)sanitizeNumber(-5, 0, { min: 0 }) // 0sanitizeNumber(999, 0, { max: 100 }) // 100处理顺序:非有限判断 → integer 取整 → min 钳制 → max 钳制。
关键设计:min / max 自身也做非有限过滤。
sanitizeNumber(5, 0, { min: NaN, max: Infinity })// 5 —— 坏的 min/max 不会把 NaN 带回结果为什么重要:min / max 通常来自用户的 props(<lh-slider :min="NaN">),如果不过滤,Math.max(NaN, 5) 就是 NaN,净化了个寂寞。
clamp(12, 0, 10) // 10clamp(-3, 0, 10) // 0clamp(5, 0, 10) // 5clamp(NaN, 0, 10) // NaN —— 透传!clamp 是朴素的 Math.min(Math.max(value, min), max),不做净化。这是刻意的:
- 调用方已保证有限的场景不需要重复净化的开销——input-number 的
clampValue、slider 的拖拽钳制、popper 的几何夹回都属此类(值来自自己算出来的中间结果)。 - 保持 NaN 透传语义:某些场景需要「NaN 就是 NaN」流到边界检查那一步,统一吃掉反而掩盖 bug。
选型原则:值来自外部(props、用户输入、网络)→ sanitizeNumber;值来自内部计算 → clamp。
safePrecision
Section titled “safePrecision”safePrecision(2) // 2safePrecision(-1) // 0safePrecision(999) // 100safePrecision(NaN) // 0safePrecision(2.7) // 2(先取整)等价于 sanitizeNumber(precision, 0, { min: 0, max: LH_PRECISION_MAX, integer: true })。
为什么必须净化:(1.234).toFixed(precision) 在 precision > 100 时抛 RangeError——一个非法的 precision prop 会直接崩掉 input-number / statistic 的渲染。净化成 0 比崩渲染好得多。
| 消费者 | 用法 |
|---|---|
pagination |
sanitizeNumber(currentPage, 1, { min: 1 }) |
input-number |
sanitizeNumber(props.step, 1, { min: 0 }) + safePrecision(props.precision) |
space |
sanitizeNumber(props.size, 8)(间距) |
popper |
入参 rect 的字段级净化 + clamp 夹回 |
keyboard |
clamp 用于导航边界 |
statistic |
safePrecision(props.precision) |
props 净化
Section titled “props 净化”// pagination 组件const currentPage = computed(() => sanitizeNumber(props.currentPage, 1, { min: 1, max: totalPages.value }),)// 从事件取值后净化const value = sanitizeNumber(Number(e.target.value), 0)precision 安全
Section titled “precision 安全”const display = modelValue.value.toFixed(safePrecision(props.precision))integer是向 0 截断(Math.trunc),不是四舍五入:3.7 → 3,-3.7 → -3。分页、下标这类场景要的就是截断。clamp不净化:这是特性不是 bug,别「修复」成净化的(会破坏 NaN 透传的调试价值)。- fallback 是必填的:没有合理默认值(不同场景的「安全值」不同),强制传让调用方想清楚。
@lh-ui/share/core/sanitize → sanitizeNumber( )返回值
(填好参数后点运行)Copyright © 2024-2026 风默文学 | 宁ICP备2024006574号 |
苏公网安备32040002010537