你见过那个输入框。你输了数字,等了三秒短信没来,翻了垃圾箱,点了"重新发送",又输了一遍数字,最后承认2FA是现代网络最重要也最烦人的发明。今天,至少在Rust这边,我们让它稍微不那么烦人一点。我们发布了OTP RS。
OTP RS到底是什么
![]()
OTP RS是一个可组合、无障碍、带动画的验证码输入组件,面向Yew、Dioxus和Leptos三个框架。它实现了完整的验证流程:逐格输入、键盘导航、激活/已填/无效/禁用状态、光标闪烁动画、数字入场弹跳动画,以及RFC 4226(HOTP)和RFC 6238(TOTP)校验。全部用Rust写,全部跑在WASM上,一行JavaScript都不用碰。
如果你试过从零搭一个六格验证码输入框,你懂那套流程。一开始想的是"不就是六个输入框"。两小时后你在调焦点管理、退格传播、键盘事件边界情况、浏览器自动填充劫持状态,还有iOS那个死活不出现的隐形数字键盘。这就是OTP RS的起源故事。
组件怎么拼
OTP RS沿用了Open SASS Kit里其他组件的可组合结构,你需要什么就拼什么:
- Otp:根容器,持有内部值状态、焦点协调和RFC校验回调。
- Group:一组视觉上聚在一起的格子,比如三位数字、一个分隔符、再来三位。
- Slot:单个格子,在一个不可见的覆盖层input之上渲染可见的字符显示。
- Separator:组与组之间那个小短横。
用法就是这样:在Otp里设好max_length和aria_label,然后按顺序摆Group、Slot和Separator。焦点管理、数字传播、状态聚合、ARIA属性全都处理好了,你只管拼格子。
那个"隐形"的输入框
OTP RS里最重要的一个设计决定是:接收键盘事件的input元素完全不可见。每个Slot渲染两层——一层是不可见的input,通过input-rs的otp_mode开启,绝对定位、铺满、透明度为零,它捕获所有键盘焦点和输入事件;另一层是可见的span,显示数字字符和闪烁的光标。
这样就把输入机制和视觉呈现拆开了,格子的外观完全由你控制,不用再跟浏览器默认的input样式较劲。
这里有个早期狠狠咬了我们一口的bug。上面这套设计只有在隐形input的CSS作为内联style属性应用时才成立,而不是作为class属性。组件最初把覆盖层CSS字符串传给了input_class,这个prop设置的是HTML的class属性。浏览器不会根据塞在class属性里的CSS属性字符串来渲染元素,它只会在样式表里查类名。结果我们得到的不是隐形覆盖层,而是一个白色矩形,气势汹汹地盖住整个验证码组件,像电视直播里被打码的表情。
修复方式是在三个框架实现里都给input-rs加了一个input_style属性,把它作为style应用到那个otp_mode的input上。每个框架一行,六个字符的差别,三个框架,三个PR的折磨。
编译器是敌人,也是最好的朋友
来数数这次Rust是怎么跟我们打的。
第一集:宏里的Hook。我们试图在html!宏的属性里调用use_state,Yew禁止在函数组件体之外调用hook。宏会展开成闭包,而hook调用必须在顶层。把use_state调用提取成html!之前的let绑定就解决了。
第二集:Box::leak和&'static str的义务。Dioxus和Leptos的input-rs属性要求&'static str,但我们像"Digit 3"这样的格子专属字符串是运行时算出来的。要把运行时String变成&'static str,又不引入字符串驻留器,唯一的办法就是Box::leak。是的,每次Slot渲染都会泄漏内存,大约15字节。理想吗?不。能编译吗?能。正确的长期方案是input-rs里加一个Signal属性类型,那是未来的PR。眼下:Box::leak,然后继续走。
第三集:那个搞崩Leptos的as转换。Leptos的view!宏无法内联解析Rust的转换表达式,宏看到as关键字就糊涂了,分不清哪是属性名哪是类型表达式。修复方式是在view!调用之前提取成let绑定。
第四集:Dioxus rsx!里的String和&str。Dioxus的rsx!宏对属性类型很严格,当slot_class是String时,宏会拒绝,因为format!产生的是String,而它要的是&str。
这些坑一个接一个,每个都值十分钟的编译等待。我们把它写出来,是希望它能帮你省下那十分钟。
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.