1个不稳定版本
0.1.0 | 2023年12月5日 |
---|
#571 in WebAssembly
28KB
375 代码行(不含注释)
wasm-yew-canvas-checkcode
纯前端yew.rs
图形验证码控件。不同于从后端拉取图形验证码图片,该控件以更“轻量级”的技术手段抑制UI
用户重复地连续提交表单。
工作原理
-
借助
rand crate
,本地生成随机字符串。 -
经由
web_sys crate
,操作Canvas 2D
平面渲染引擎,生成图形验证码图片。在图片中的- 背景色
- 背景星型图案
- 每个星型图案的角数(3 ~ 8)、位置、旋转、颜色、密度
- 每位验证字符的位置、旋转、颜色,间距
都是被即时演算出来的。
-
通过被传入控件的【回调函数】
on_check_code_change(CheckCode)
,将被生成的随机字符串验证码返回给父控件。
::wasm_yew_canvas_checkcode::CanvasCheckCode
图形验证码控件自身。在渲染函数中,其被记为<CanvasCheckCode>
。
::wasm_yew_canvas_checkcode::Message
控件的枚举类内部状态集::wasm_yew_canvas_checkcode::CheckCode
包装了图形验证码字符串的枚举类::CheckCode::Initialize(String)
代表控件初始化过程生成的图形验证码::CheckCode::Update(String)
代表由UI鼠标点击事件或父控件程序触发生成的图形验证码-
控件输入参数列表
-
width
- u64
- 可选参数
单位:像素
-
图形验证码canvas画布的宽度
默认值优先次序:
150
- height
- u64
- 图形验证码canvas画布的高度
- 默认值
50
- star_size
u64:
150
- height
- u64
- 可选参数
- 默认值
50
- 单位:像素
背景随机星型图案的大小尺寸。因为星型图案的BBox是正方形,所以这里仅需要设置一个值。:
150
- height
- u64
- 默认值
7
star_count: u8
- height
- 单位:个
- 背景随机星型图案的最多个数。
- 默认值
25
:150
- height
- u64
- font_size
- u64
可选参数: u8
- height
- 单位:个
- 单位:像素
- 验证码单个字符的最大尺寸
默认值:
22
<check_code_len>- u8
- 可选参数
- 验证码的字符个数
- 控件输入参数列表
CheckCode::Update(String)
表示由UI
点击事件或程序触发的图形验证码
- 没有返回值
- 验证码的字符个数
- 功能:向父控件反馈最新生成的验证码字符串。
reversed_hook:
22
<作用域<CanvasCheckCode>>-
height
-
可选参数
- 形式参数
Scope<CanvasCheckCode>
代表<CanvasCheckCode>
控件的【作用域】对象。 - 没有返回值
- 形式参数
-
功能:向父控件传递
<CanvasCheckCode>
【作用域】对象(副本),以允许从控件外部程序地触发新图形验证码的生成操作。例如,- 首先,通过
Rc<RefCell<Option<Scope<CanvasCheckCode>>>>
字段值,缓存被上传的<CanvasCheckCode>
【作用域】对象副本。 - 其次,在
fn view(..) -> bool
生命周期函数内,程序地触发<CanvasCheckCode>
子控件重新生成图形验证码。
self.check_code_scope.borrow().as_ref().map(|scope| { scope.send_message(CanvasCheckCodeMessage::UpdateCheckCode); });
- 首先,通过
-
默认值表示不执行任何操作
-
总结,最后两个控件输入参数都是回调函数。它们的功能都是从下向上,从<CanvasCheckCode>
向父控件传递返回值的
on_check_code_change
返回最新的图形验证码字符串。reversed_hook
返回程序触发生成新图形验证码的“操作句柄”。
控件输出回调函数钩子
<CanvasCheckCode>
控件以回调函数的方式向父控件回传
- 最新被生成的图形验证码字符串 —— 用以校对
UI
用户敲入的图形验证码字符串是否正确。 - 自身作用域对象
Scope<CanvasCheckCode>
—— 用以程序地从父控件触发新图形验证码的生成。
从父控件获取最新图形验证码字符串
回调函数签名on_check_code_change: |check_code: CheckCode| -> () { .. }
- 回调函数的返回值是
unit type
- 形参是枚举类
CheckCode
-
控件输入参数列表
-
width
- u64
- 可选参数
单位:像素
-
例程
use ::wasm_yew_canvas_checkcode::CheckCode;
//
yew::props![CanvasCheckCodeProps {
on_check_code_change: |check_code| {
let check_code = match check_code {
CheckCode::Initialize(value) => value,
CheckCode::Update(value) => value,
};
console::info!("从父组件收到的校验码", check_code);
}
}]
从父控件程序地刷新图形验证码
回调函数签名reversed_hook: |my_scope: Scope<CanvasCheckCode>| -> () { .. }
- 回调函数的返回值是
unit type
- 形参是
Scope<CanvasCheckCode>
首先,获取<CanvasCheckCode>
子控件的作用域对象Scope<CanvasCheckCode>
。
然后,在父控件的结构体字段<child1_scope: Rc<RefCell<Option<Scope<CanvasCheckCode>>>>
内缓存该作用域对象。
use ::wasm_yew_canvas_checkcode::CheckCode;
//
yew::props![CanvasCheckCodeProps {
reversed_hook: |my_scope| {
// 在父控件中,缓存子控件的`scope`对象
child1_scope.borrow_mut().replace(my_scope);
}
}]
最后,在父控件的fn update( .. ) -> bool
生命周期函数内,修改子控件<CanvasCheckCode>
的状态集以触发新的图形验证码被生成。
fn update(&mut self, ctx: &Context<Self>, msg: Self::Message) -> bool {
let props = ctx.props();
match msg {
Message::SubmitForm => {
self.child1_scope.borrow().as_ref().map(|child1_scope| { // 从父控件,触发子控件刷新图形验证码
child1_scope.send_message(CanvasCheckCodeMessage::UpdateCheckCode);
});
return false;
}
_ => ()
}
true
}
附赠两个例程
此crate
以【**(有脸)**集成测试】的方式,提供两个例程
仅图形验证码控制简单例程
例程文件:tests\simple.rs
启动命令行指令:wasm-pack test --chrome --test=simple
演示内容:
<CanvasCheckCode>
控件被直接加到DOM
流中,作为整个wasm-webapp
的根组件。- 点击
<CanvasCheckCode>
控件会刷新图形验证码字符串
登录表单半成品(实战)例程
例程文件:tests\form.rs
启动命令行指令:wasm-pack test --chrome --test=form
演示内容:
wasm-webapp
的根组件是一个【用户名/密码/图形验证码】的常规网页登录表单。- 集成测试执行流被阻塞。只有当
UI
用户输入了正确的图形验证码,才能开始表单验证。 - 点击
<CanvasCheckCode>
控件会刷新图形验证码字符串,同时清空图形验证码的文本输入框。 - 点击【登录】按钮,会比较从
<CanvasCheckCode>
控件回传给父控件的图形验证码“真身”与用户输入的图形验证码字符串是否一致。 - 如果两个图形验证码字符串一致,则集成测试成功通过。
- 否则,集成测试失败
依赖项
~11–15MB
~264K SLoC