1 unstable release
0.1.0 | Dec 5, 2023 |
---|
#582 in WebAssembly
28KB
375 lines
wasm-yew-canvas-checkcode
纯前端yew.rs
图形验证码控件。不同于从后端拉取图形验证码图片,该控件以更“轻量级”的技术手段抑制UI
用户重复地连续提交表单。
工作原理
-
借助
rand crate
,本地生成随机字符串。 -
经由
web_sys crate
,操作Canvas 2D
平面渲染引擎,生成图形验证码图片。在图片中的- 背景色
- 背景星型图案
- 每个星型图案的角数(3 ~ 8)、位置、旋转、颜色、密度
- 每位验证字符的位置、旋转、颜色,间距
都是被即时演算出来的。
-
通过被传入控件的【回调函数】
on_check_code_change(CheckCode)
,将被生成的随机字符串验证码返回给父控件。
crate
导出项清单
::wasm_yew_canvas_checkcode::CanvasCheckCode
图形验证码控件自身。在渲染函数中,其被记为<CanvasCheckCode>
。::wasm_yew_canvas_checkcode::Message
控件的枚举类内部状态集::wasm_yew_canvas_checkcode::Props
控件的输入参数属性集::wasm_yew_canvas_checkcode::CheckCode
包装了图形验证码字符串的枚举类-
CheckCode::Initialize(String)
代表控件初始化过程生成的图形验证码 -
CheckCode::Update(String)
代表由UI
鼠标点击事件或- 父控件程序触发
生成的图形验证码
-
控件输入参数列表
width: f64
- 可选参数
- 单位:像素
- 图形验证码
canvas
画布的宽度 - 默认值优先次序
css
样式表设置的宽度- 缺省值
150
height: f64
- 可选参数
- 单位:像素
- 图形验证码
canvas
画布的高度 - 默认值优先次序
css
样式表设置的宽度- 缺省值
50
star_size: f64
- 可选参数
- 单位:像素
- 背景随机星型图案的大小尺寸。因为星型图案的
BBox
是正方形,所以这里仅只需要设置一个值。 - 默认值
7
star_count: u8
- 可选参数
- 单位:个
- 背景随机星型图案的最多个数。
- 默认值
25
。在图形渲染过程中,虽然做了星型图形的BBox
碰撞测试,但若星型图案太多,还是会出现星型图案的重叠现象。
font_size: f64
- 可选参数
- 单位:像素
- 验证码单个字符的最大尺寸
- 默认值
22
。
check_code_len: u8
- 可选参数
- 单位:个
- 验证码的字符个数
- 默认值
5
。字符太多也会出现重叠现象,虽然程序也对单个验证码字符的BBox
做过碰撞测试了。
on_check_code_change: Callback<CheckCode>
- 必填参数
- 类型:事件回调函数。
- 形参
CheckCode
是枚举值CheckCode::Initialize(String)
代表控件初始化过程生成的图形验证码CheckCode::Update(String)
代表由UI
点击事件或程序触发生成的图形验证码
- 没有返回值
- 形参
- 功能:向父控制反馈最新生成的验证码字符串。
reversed_hook: Callback<Scope<CanvasCheckCode>>
-
可选参数
-
类型:事件回调函数。
- 形参
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
-
CheckCode::Initialize(String)
代表控件初始化过程生成的图形验证码 -
CheckCode::Update(String)
代表由UI
鼠标点击事件或- 父控件程序触发
生成的图形验证码
-
例程
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>
控件被做为整个wasm-webapp
的根组件直接加到DOM
流中。- 点击
<CanvasCheckCode>
控件会刷新图形验证码字符串
登录表单半成品(实战)例程
例程文件:tests\form.rs
启动命令行指令:wasm-pack test --chrome --test=form
演示内容:
wasm-webapp
的根组件是一个【用户名/密码/图形验证码】的常规网页登录表单。- 集成测试执行流被阻塞。并且,仅当
UI
用户录入了正常的图形验证码才能开始表单验证。 - 点击
<CanvasCheckCode>
控件会刷新图形验证码字符串,同时置空图形验证码的文本输入框。 - 点击【登录】按钮,会比较从
<CanvasCheckCode>
控件回传给父控件的图形验证码“本尊”与用户录入的图形验证码字符串是否一致。 - 若两个图形验证码字符串一致,则集成测试成功通过。
- 否则,集成测试失败
Dependencies
~11–20MB
~275K SLoC