@@ -7,18 +7,22 @@ interface Props {
77 value ?: string ; // 由父级传入指定的字符串生成code
88 width ?: number ; // 多宽 px
99 height ?: number ; // 多高 px
10- style ?: object ; // 自定义style
10+ style ?: {
11+ [ propName : string ] : any ;
12+ } ; // 自定义style
1113 className ?: string ; // 各种class
1214 options ?: OptionsProps ; // 自定义各参数
13- onChange ?: Function ; // 每次生成新的验证码时,将验证码的值传到上级
14- onClick ?: Function ; // 用户每次点击时触发
15+ onChange ?: ( p : string | null ) => any ; // 每次生成新的验证码时,将验证码的值传到上级
16+ onClick ?: ( ) => any ; // 用户每次点击时触发
1517}
1618interface State {
1719 id : string ;
1820 width : number ;
1921 height : number ;
2022 len : number ;
21- style : object ;
23+ style : {
24+ [ propName : string ] : any ;
25+ } ;
2226 options : Options ;
2327}
2428
@@ -66,7 +70,44 @@ export default class Vcode extends React.PureComponent<Props, State> {
6670 options : ( ( ) => {
6771 // 初始化参数
6872 const a : Options = {
69- codes : [ "a" , "b" , "c" , "d" , "e" , "f" , "g" , "h" , "i" , "j" , "k" , "l" , "m" , "o" , "p" , "q" , "r" , "s" , "t" , "x" , "u" , "v" , "y" , "z" , "w" , "n" , "0" , "1" , "2" , "3" , "4" , "5" , "6" , "7" , "8" , "9" ] ,
73+ codes : [
74+ "a" ,
75+ "b" ,
76+ "c" ,
77+ "d" ,
78+ "e" ,
79+ "f" ,
80+ "g" ,
81+ "h" ,
82+ "i" ,
83+ "j" ,
84+ "k" ,
85+ "l" ,
86+ "m" ,
87+ "o" ,
88+ "p" ,
89+ "q" ,
90+ "r" ,
91+ "s" ,
92+ "t" ,
93+ "x" ,
94+ "u" ,
95+ "v" ,
96+ "y" ,
97+ "z" ,
98+ "w" ,
99+ "n" ,
100+ "0" ,
101+ "1" ,
102+ "2" ,
103+ "3" ,
104+ "4" ,
105+ "5" ,
106+ "6" ,
107+ "7" ,
108+ "8" ,
109+ "9" ,
110+ ] ,
70111 fontSizeMin : 22 , // 字体尺寸最小值
71112 fontSizeMax : 26 , // 字体尺寸最大值
72113 colors : [
@@ -109,16 +150,20 @@ export default class Vcode extends React.PureComponent<Props, State> {
109150 }
110151
111152 /** 组件初始化完毕时触发 **/
112- componentDidMount ( ) {
153+ componentDidMount ( ) : void {
113154 this . onDraw ( this . props . value ) ;
114155 }
115156
116157 /** 组件参数改变 **/
117- componentDidUpdate ( prevP : Props ) {
158+ componentDidUpdate ( prevP : Props ) : void {
118159 if ( this . props . value !== prevP . value ) {
119160 this . onDraw ( this . props . value ) ;
120161 }
121- if ( this . props . width !== prevP . width || this . props . height !== prevP . height || this . props . style !== prevP . style ) {
162+ if (
163+ this . props . width !== prevP . width ||
164+ this . props . height !== prevP . height ||
165+ this . props . style !== prevP . style
166+ ) {
122167 this . setState ( {
123168 width : this . props . width || 150 ,
124169 height : this . props . height || 40 ,
@@ -131,7 +176,7 @@ export default class Vcode extends React.PureComponent<Props, State> {
131176 }
132177
133178 /** 用户点击了验证码图片 **/
134- onClick ( ) {
179+ onClick ( ) : void {
135180 // 如果用户没有设置值,就直接重新生成
136181 if ( ! this . props . value ) {
137182 this . onDraw ( this . props . value ) ;
@@ -147,8 +192,15 @@ export default class Vcode extends React.PureComponent<Props, State> {
147192 */
148193 codeCss ( uW : number , i : number ) : string {
149194 return [
150- `font-size:${ this . randint ( this . state . options . fontSizeMin , this . state . options . fontSizeMax ) } px` ,
151- `color:${ this . state . options . colors [ this . randint ( 0 , this . state . options . colors . length - 1 ) ] } ` ,
195+ `font-size:${ this . randint (
196+ this . state . options . fontSizeMin ,
197+ this . state . options . fontSizeMax
198+ ) } px`,
199+ `color:${
200+ this . state . options . colors [
201+ this . randint ( 0 , this . state . options . colors . length - 1 )
202+ ]
203+ } `,
152204 "position: absolute" ,
153205 `left:${ this . randint ( uW * i , uW * i + uW - uW / 2 ) } px` ,
154206 "top:50%" ,
@@ -157,7 +209,11 @@ export default class Vcode extends React.PureComponent<Props, State> {
157209 `-ms-transform:rotate(${ this . randint ( - 15 , 15 ) } deg) translateY(-50%)` ,
158210 `-moz-transform:rotate(${ this . randint ( - 15 , 15 ) } deg) translateY(-50%)` ,
159211 `-webkit-transform:rotate(${ this . randint ( - 15 , 15 ) } deg) translateY(-50%)` ,
160- `font-family:${ this . state . options . fonts [ this . randint ( 0 , this . state . options . fonts . length - 1 ) ] } ` ,
212+ `font-family:${
213+ this . state . options . fonts [
214+ this . randint ( 0 , this . state . options . fonts . length - 1 )
215+ ]
216+ } `,
161217 "font-weight:bold" ,
162218 "z-index:2" ,
163219 ] . join ( ";" ) ;
@@ -171,17 +227,34 @@ export default class Vcode extends React.PureComponent<Props, State> {
171227 return [
172228 "position: absolute" ,
173229 `opacity:${ this . randint ( 3 , 8 ) / 10 } ` ,
174- `width:${ this . randint ( this . state . options . lineWidthMin , this . state . options . lineWidthMax ) } px` ,
175- `height:${ this . randint ( this . state . options . lineHeightMin , this . state . options . lineHeightMax ) } px` ,
176- `background:${ this . state . options . lineColors [ this . randint ( 0 , this . state . options . lineColors . length - 1 ) ] } ` ,
177- `left:${ this . randint ( - this . state . options . lineWidthMin / 2 , this . state . width ) } px` ,
230+ `width:${ this . randint (
231+ this . state . options . lineWidthMin ,
232+ this . state . options . lineWidthMax
233+ ) } px`,
234+ `height:${ this . randint (
235+ this . state . options . lineHeightMin ,
236+ this . state . options . lineHeightMax
237+ ) } px`,
238+ `background:${
239+ this . state . options . lineColors [
240+ this . randint ( 0 , this . state . options . lineColors . length - 1 )
241+ ]
242+ } `,
243+ `left:${ this . randint (
244+ - this . state . options . lineWidthMin / 2 ,
245+ this . state . width
246+ ) } px`,
178247 `top:${ this . randint ( 0 , this . state . height ) } px` ,
179248 `transform:rotate(${ this . randint ( - 30 , 30 ) } deg)` ,
180249 `-o-transform:rotate(${ this . randint ( - 30 , 30 ) } deg)` ,
181250 `-ms-transform:rotate(${ this . randint ( - 30 , 30 ) } deg)` ,
182251 `-moz-transform:rotate(${ this . randint ( - 30 , 30 ) } deg)` ,
183252 `-webkit-transform:rotate(${ this . randint ( - 30 , 30 ) } deg)` ,
184- `font-family:${ this . state . options . fonts [ this . randint ( 0 , this . state . options . fonts . length - 1 ) ] } ` ,
253+ `font-family:${
254+ this . state . options . fonts [
255+ this . randint ( 0 , this . state . options . fonts . length - 1 )
256+ ]
257+ } `,
185258 `font-weight:${ this . randint ( 400 , 900 ) } ` ,
186259 ] . join ( ";" ) ;
187260 }
@@ -190,33 +263,43 @@ export default class Vcode extends React.PureComponent<Props, State> {
190263 * 绘制
191264 * @param value 需要生成的字符值,不传则随机生成
192265 * */
193- onDraw ( value : string | undefined ) {
266+ onDraw ( value : string | undefined ) : string | null {
194267 let c = "" ; // 存储生成的code
195268 const div = document . getElementById ( this . state . id ) ;
196269
197- const isImg : boolean = / ^ h t t p [ s ] * : \/ \/ | \. j p g $ | \. p n g $ | \. j p e g $ | \. g i f $ | \. b m p $ | \. w e b p $ | ^ d a t a : i m a g e / . test ( value || "" ) ; // 是否是图片
270+ const isImg : boolean = / ^ h t t p [ s ] * : \/ \/ | \. j p g $ | \. p n g $ | \. j p e g $ | \. g i f $ | \. b m p $ | \. w e b p $ | ^ d a t a : i m a g e / . test (
271+ value || ""
272+ ) ; // 是否是图片
198273 if ( div ) {
199274 div . innerHTML = "" ;
200275 }
201276
202277 if ( isImg ) {
203278 // 用户传递了一张图片
204279 const dom = document . createElement ( "img" ) ;
205- dom . style . cssText = [ "display: block" , "max-width:100%" , "max-height:100%" ] . join ( ";" ) ;
280+ dom . style . cssText = [
281+ "display: block" ,
282+ "max-width:100%" ,
283+ "max-height:100%" ,
284+ ] . join ( ";" ) ;
206285 dom . src = value as string ;
207286 div && div . appendChild ( dom ) ;
208287 this . props . onChange && this . props . onChange ( null ) ;
209288 return null ;
210289 }
211290
212291 // 不是图片而是普通字符串, 如果value存在说明是用户自定义的字符串
213- let length = value ? value . length : this . state . len ; // 字符的长度
292+ const length = value ? value . length : this . state . len ; // 字符的长度
214293
215294 const uW : number = this . state . width / length / 1.01 ; // 每个字符占的宽度
216295 for ( let i = 0 ; i < length ; i ++ ) {
217296 const dom = document . createElement ( "span" ) ;
218297 dom . style . cssText = this . codeCss ( uW , i ) ;
219- const temp = value ? value [ i ] : this . state . options . codes [ Math . round ( Math . random ( ) * ( this . state . options . codes . length - 1 ) ) ] ;
298+ const temp = value
299+ ? value [ i ]
300+ : this . state . options . codes [
301+ Math . round ( Math . random ( ) * ( this . state . options . codes . length - 1 ) )
302+ ] ;
220303 dom . innerHTML = String ( temp ) ;
221304 c = `${ c } ${ temp } ` ;
222305 div && div . appendChild ( dom ) ;
@@ -240,6 +323,13 @@ export default class Vcode extends React.PureComponent<Props, State> {
240323 }
241324
242325 render ( ) {
243- return < div id = { this . state . id } style = { this . state . style } className = { this . props . className } onClick = { ( ) => this . onClick ( ) } /> ;
326+ return (
327+ < div
328+ id = { this . state . id }
329+ style = { this . state . style }
330+ className = { this . props . className }
331+ onClick = { ( ) => this . onClick ( ) }
332+ />
333+ ) ;
244334 }
245335}
0 commit comments