资讯动态

React IMask 使用指南:为 React 输入框集成 imask 掩码组件

发布时间:2026/10/14 13:22:27 来源:尧图企业网站定制
前端UI组件【免费下载链接】imaskjsvanilla javascript input mask项目地址https://gitcode.com/gh_mirrors/im/imaskjs点击查看免费下载本文基于 imaskjs 仓库中的react-imask插件文档系统讲解如何在 React 应用中为输入框集成掩码input mask能力从最常用的IMaskInput组件、unmask三态取值、onAccept事件到通过IMaskMixin扩展已有自定义组件、以及使用useIMaskHook 实现完全可控的受控输入。读完本文你将掌握三种接入方式的使用边界与内部原理能够直接套用到数字、日期、电话等格式化场景。一、安装与环境要求react-imask是 imaskjs 项目中面向 React 的官方封装通过 npm 安装即可npm install react-imask安装后包会同时把核心依赖imask^7.6.1与prop-types^15.8.1一并带入。根据 package.json 中的声明React 版本要求peerDependencies为react 0.14.0也就是说从 React 0.14 起的旧版本到 React 18 均可使用Node/npm 要求engines.npm 4.0.0ESM/CommonJS 双格式exports字段同时提供import./esm/index.js与require./dist/react-imask.cjs两种入口TypeScript 类型声明位于esm/index.d.ts支持typesVersions 4.2的类型解析。react-imask的公共 API 集中在 src/index.ts共导出四个核心成员import imask; export { default as IMask } from imask; // 底层 IMask 命名空间 export { default as IMaskInput } from ./input; // 开箱即用的输入组件 export { default as useIMask } from ./hook; // React Hook 方式 export { default as IMaskMixin, ... } from ./mixin; // 高阶组件方式也就是说一个包同时提供了组件、HOC、Hook 三种接入形态下文逐一展开。二、快速开始使用IMaskInput组件最直接的方式是使用react-imask导出的IMaskInput组件。它默认渲染一个原生input并把所有掩码相关配置作为 props 传入import { useRef } from react; import { IMaskInput } from react-imask; // use ref to get access to internal masked ref.current.maskRef const ref useRef(null); const inputRef useRef(null); IMaskInput mask{Number} radix. value123 unmask{true} // true|false|typed ref{ref} inputRef{inputRef} // access to nested input // DO NOT USE onChange TO HANDLE CHANGES! // USE onAccept INSTEAD onAccept{ // depending on prop above first argument is // value if unmaskfalse, // unmaskedValue if unmasktrue, // typedValue if unmasktyped (value, mask) console.log(value) } // ...and more mask props in a guide // input props also available placeholderEnter number here /这个例子覆盖了最常用的一组 props其中几个关键点说明如下mask{Number}数字掩码。imask 会根据 mask 的类型自动创建对应的掩码模型底层由createMask/maskedClass分发见 packages/imask/src/masked/factory.ts字符串 → 模式掩码MaskedPatternRegExp→MaskedRegExpDate→MaskedDateNumber→MaskedNumber数组 → 动态掩码MaskedDynamic普通函数 → 函数掩码MaskedFunction。radix.小数点分隔符。注意 MaskedNumber 的默认值 是radix: ,欧洲风格逗号示例中显式改为.。value123初始展示值属于受控值注入组件内部会把它写入掩码模型。unmask控制onAccept回调拿到的值形态详见下一节。ref与inputRef前者拿到组件实例可访问ref.current.maskRef获取底层 InputMask 对象后者直接拿到内部inputDOM 节点。不要用onChange处理掩码值变化改用onAccept掩码在输入过程中会不断改写 DOM 值onChange拿到的原始事件与掩码模型不同步官方明确建议使用onAccept。组件同时透传原生 input 属性例如placeholder、className、type等因此它可以无缝替换普通input。三、unmask三态与onAccept/onComplete事件3.1unmask决定回调的第一个参数unmask接受true、false、typed三个取值直接决定onAccept、onComplete回调第一个参数的内容README 中明确列出unmask取值回调第一个参数含义false默认value掩码格式化后的字符串如123.45含掩码符号trueunmaskedValue去掉掩码符号的纯字符串如12345typedtypedValue按掩码类型转换后的强类型值如数字12345、Date对象这一逻辑在源码中由maskValue的 getter 精确实现packages/react-imask/src/mixin.tsget maskValue () { if (!this.maskRef) return ; if (this.props.unmask typed) return this.maskRef.typedValue; if (this.props.unmask) return this.maskRef.unmaskedValue; return this.maskRef.value; }对应的valueprop 在设置时也会按同样的规则写入unmask typed时赋值maskRef.typedValueunmask true时赋值unmaskedValue否则赋值valuemixin.ts。因此valueprop 的语义会随unmask联动——这是使用受控模式时最容易踩的坑务必保证提交给组件的value与unmask取值匹配。3.2 事件的第二个参数maskRefonAccept与onComplete的签名都是(value, mask, e?) void第二个参数是InputMask实例即maskRef可继续访问mask.value、mask.unmaskedValue、mask.typedValue、mask.updateOptions()等方法InputMask 类的完整能力见 packages/imask/src/controls/input.ts第三个可选参数是触发事件的InputEvent。两者的触发时机来自底层 imask 的事件系统InputMask在模型变化时通过_fireChangeEvents()触发accept当masked.isComplete掩码填满时额外触发completeinput.ts。对应到 React 层onAccept每次掩码值被接受每次有效输入都会触发onComplete掩码完整填满时触发一次。底层事件绑定发生在initMask中initMask (maskOptions) { this.maskRef IMask(this.element, maskOptions) .on(accept, this._onAccept.bind(this)) .on(complete, this._onComplete.bind(this)); ... }3.3 事件与 props 提取的源码实现IMaskMixin内部通过MASK_PROPS白名单mixin.ts区分哪些 props 属于掩码选项、哪些属于普通 React 属性_extractMaskOptionsFromProps从 props 中过滤出掩码选项传给IMask(element, options)初始化_extractNonMaskProps反向剥离掩码选项把剩余 props 交给被包裹的组件渲染同时若未提供defaultValue会以props.mask ? : props.value作为默认值mixin.ts。生命周期处理也集中在 mixin 内mixin.tscomponentDidMount存在maskprop 时调用initMask()创建InputMask实例componentDidUpdate掩码存在时调用maskRef.updateOptions()增量更新选项掩码类型变更时内部会重建模型见 input.ts 的 updateOptions若maskprop 被移除如置为null则销毁掩码并直接把value写回 DOMcomponentWillUnmount调用maskRef.destroy()释放事件监听。四、通过IMaskMixin扩展已有组件如果不想用内置的input而是希望给 styled-components、Material-UI 的TextField等自定义组件加掩码可以使用IMaskMixin高阶组件import { IMaskMixin } from react-imask; // extend style component const StyledInput styled.input color: green; ; const MaskedStyledInput IMaskMixin(({inputRef, ...props}) ( StyledInput {...props} innerRef{inputRef} // bind internal input (if you use styled-components V4, use ref instead innerRef) / )); MaskedStyledInput mask{Number} radix. onAccept{(value, mask) console.log(value)} // ...and more mask props in a guide // ...other styled props /工作原理与约束IMaskMixin接收一个函数组件该函数会收到一个特殊的inputRef回调 prop你必须把它绑定到真正承载文本输入的 DOM 元素上innerRef是 styled-components V4 之前的写法V4 及以后用ref组件渲染时mixin 会注入inputRef: this._inputRefmixin.ts_inputRef内部还会把 DOM 元素回填到用户传入的props.inputRef支持{ current }对象形式的 ref 或函数形式的 ref 回调mixin.tsmixin 返回的组件 displayName 形如IMask(ComponentName)便于调试mixin.ts底层实现上IMaskInput本身就是IMaskMixin的产物——它把React.createElement(input, { ...props, ref: inputRef })传入 mixinpackages/react-imask/src/input.ts并额外用React.forwardRef包装以支持外层ref。顺带一提IMaskMixin返回值同样支持通过ref.current.maskRef访问底层 InputMask 实例。五、使用useIMaskHook非受控 受控混合模式第三种方式是useIMaskHook适合函数组件中希望同时保留非受控输入体验、又能拿到掩码模型状态的场景import { useState } from react; import { useIMask } from react-imask; function IMaskWithHook () { const [ opts, setOpts ] useState({ mask: Number }); const { ref, maskRef, value, setValue, unmaskedValue, setUnmaskedValue, typedValue, setTypedValue, } useIMask(opts, /* optional { onAccept, onComplete, ref, defaultValue, defaultUnmaskedValue, defaultTypedValue, } */); return ( input ref{ref} / ); }Hook 返回的 7 个成员实现见 packages/react-imask/src/hook.ts返回值说明ref绑定到input的 ref默认内部创建也可通过 options 传入外部 ref 覆盖maskRef底层InputMask实例的引用{ current: InputMask | null }value/setValue掩码格式化值及其 setterunmaskedValue/setUnmaskedValue去掩码字符串值及其 settertypedValue/setTypedValue强类型值及其 setter如Number掩码下为数字第二个可选参数支持四个默认值与两个事件回调onAccept(value, maskRef, e?)、onComplete(value, maskRef, e?)与组件版语义一致defaultValue、defaultUnmaskedValue、defaultTypedValue掩码创建后分别注入三种形态的初始值。Hook 内部行为要点源自 hook.ts当ref.current存在且opts.mask非空时调用IMask(el, opts)创建掩码并存储maskRefopts引用变化时自动调用mask.updateOptions(opts)增量更新mask被移除时销毁掩码maskRef.current.destroy()每次 accept 时把value / unmaskedValue / typedValue三个状态同步刷新storeLastAcceptedValues并在 effect 中监听三者变化外部setValue等调用会写回掩码模型组件卸载时自动destroy掩码并解绑accept/complete事件监听。六、掩码 props 速查表组件可用的全部掩码选项IMaskInput/IMaskMixin组件接受的全部掩码 props 以MASK_PROPS白名单的形式定义在 mixin.ts按类别整理如下这些选项全部来自 imask 核心的FactoryOpts类型见 packages/imask/src/masked/factory.ts通用选项commonprop类型说明maskstring \| RegExp \| Number \| Date \| Array \| Function \| Masked 子类掩码定义必填为空时组件直接退化为普通输入框valueany初始/受控值语义随unmask变化unmaskboolean \| typed控制取值与回调参数形态prepare/prepareCharfunction输入前预处理字符validatefunction自定义校验commitfunction提交失焦时处理overwriteboolean \| shift是否允许覆盖已填字符eagerboolean \| append \| remove是否即时补全掩码字符skipInvalidboolean是否跳过非法输入模式掩码patternplaceholderChar占位符默认_见 MaskedPattern.DEFAULTS、displayChar已填字符显示符、lazy默认true未输入时不显示占位符、definitions自定义模式定义、blocks模式块定义。枚举掩码enumenumstring[]仅允许列表内的值。范围掩码rangemaxLength、from、to如日期块{from: 1, to: 31, maxLength: 2}。日期掩码datemask{Date}时pattern如d/m/Y、formatDate 转字符串默认dd.mm.yyyy见 MaskedDate.DEFAULTS、parse字符串转 Date、autofixboolean \| pad越界时自动修正、min/maxDate上下界。数字掩码numbermask{Number}时radix小数点默认,、thousandsSeparator千分位默认空、mapToRadix可映射为小数点的字符数组、scale小数位数默认2、normalizeZeros默认true结束编辑时去除首尾多余零、padFractionalZeros默认false结束编辑时补零、min/max数字上下界。这些默认值均可在 MaskedNumber.DEFAULTS 中核对。动态掩码dynamicdispatch根据已输入内容动态切换子掩码。事件与 refonAccept、onComplete、inputRef接收{ current }对象或回调函数mixin.ts。注意maxLength比较特殊——它既被MASK_PROPS定义为 range 掩码选项又会被_extractNonMaskProps放行if (maskProp ! maxLength)因此它既可以约束掩码块长度也可以作为原生 input 属性透传具体行为取决于mask类型。七、进阶示例日期掩码与 blocks 组合仓库自带的 example.html 演示了IMaskInput的完整日期掩码用法可作为综合实战参考const blocks { d: { mask: IMask.MaskedRange, from: 1, to: 31, maxLength: 2 }, m: { mask: IMask.MaskedRange, from: 1, to: 12, maxLength: 2 }, Y: { mask: IMask.MaskedRange, from: 1900, to: 9999 }, }; const format2 date { let day date.getDate(), month date.getMonth() 1; const year date.getFullYear(); if (day 10) day 0 day; if (month 10) month 0 month; return [year, month, day].join(-); }; const parse2 str { const ymd str.split(-); return new Date(ymd[0], ymd[1] - 1, ymd[2]); }; const min new Date(2000, 0, 1); const max new Date(2020, 0, 1); IMaskInput mask{Date} pattern{Y-m-d} blocks{blocks} format{format2} parse{parse2} min{min} max{max} autofix{true} lazy{false} overwrite{false} onAccept{(value, mask) { console.log(accept, value, typeof value, mask); this.setState({ value }); }} onComplete{(value, mask) console.log(complete!, value, mask)} placeholderEnter here /该示例展示了几个值得复用的实战技巧blockspattern组合pattern中是模式掩码的固定字符转义前缀MaskedPattern.STOP_CHAR见 packages/imask/src/masked/pattern.tsY-m-d表示固定输出连字符-blocks为每个字母块声明了取值范围MaskedRange与长度限制自定义format/parse掩码内部以Date对象为 typedValue格式化时调用format2输出YYYY-MM-DD解析时由parse2还原这印证了unmasktyped时typedValue就是Date实例min/maxautofix输入越界时如月份 13、超出 2000~2020 范围自动修正为边界值——底层由MaskedNumber/MaskedDate的doCommit边界检查逻辑支撑lazy{false}立即显示所有占位符而不是输入到哪显示到哪事件驱动状态用onAccept同步state再次强调不要依赖onChange。需要更完整的掩码选项说明时可继续阅读仓库根目录 README.md 与核心包 packages/imask/README.md并参考 packages/imask/src/masked 下各掩码类的DEFAULTS定义核对默认行为。八、总结三种接入方式怎么选方式适用场景关键能力IMaskInput大多数表单场景直接替换原生 input零配置、透传原生属性、ref.current.maskRef访问底层实例IMaskMixin需要给 styled-components / 第三方输入组件加掩码任意组件包装、inputRef绑定真实输入元素useIMask函数组件中需要受控读写掩码三态值value / unmaskedValue / typedValue三对读写状态 自动生命周期管理无论采用哪种方式都请牢记两条核心实践用onAccept/onComplete而不是onChange处理掩码值value、onAccept的参数形态必须与unmask的取值保持一致。结合本文的 props 速查表与源码层面的生命周期说明即可在 React 项目中稳定落地数字、日期、枚举、动态等各类输入掩码。赞分享前端UI组件【免费下载链接】imaskjsvanilla javascript input mask项目地址https://gitcode.com/gh_mirrors/im/imaskjs点击查看免费下载相关推荐rsuite Input 输入框组件完全指南从基础用法、输入框组合到掩码输入rsuite Input 输入框组件完全指南从基础用法、输入框组合到掩码输入 本指南以 rsuite 文档站 docs/pages/components/in前端UI组件推荐使用React Native文本输入掩码库推荐使用React Native文本输入掩码库 在移动应用开发中处理用户输入的格式化问题是一项挑战尤其是涉及到电话号码、信用卡号等特定格式的数据时。这就是上一篇SnapRAID完整配置指南从零开始设置你的备份系统下一篇使用 Datadog Helm Chart 在 Kubernetes 集群部署 Agent、Cluster Agent 与监控采集能力创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑