@@ -7,18 +7,22 @@ interface Props {
7
7
value ?: string ; // 由父级传入指定的字符串生成code
8
8
width ?: number ; // 多宽 px
9
9
height ?: number ; // 多高 px
10
- style ?: object ; // 自定义style
10
+ style ?: {
11
+ [ propName : string ] : any ;
12
+ } ; // 自定义style
11
13
className ?: string ; // 各种class
12
14
options ?: OptionsProps ; // 自定义各参数
13
- onChange ?: Function ; // 每次生成新的验证码时,将验证码的值传到上级
14
- onClick ?: Function ; // 用户每次点击时触发
15
+ onChange ?: ( p : string | null ) => any ; // 每次生成新的验证码时,将验证码的值传到上级
16
+ onClick ?: ( ) => any ; // 用户每次点击时触发
15
17
}
16
18
interface State {
17
19
id : string ;
18
20
width : number ;
19
21
height : number ;
20
22
len : number ;
21
- style : object ;
23
+ style : {
24
+ [ propName : string ] : any ;
25
+ } ;
22
26
options : Options ;
23
27
}
24
28
@@ -66,7 +70,44 @@ export default class Vcode extends React.PureComponent<Props, State> {
66
70
options : ( ( ) => {
67
71
// 初始化参数
68
72
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
+ ] ,
70
111
fontSizeMin : 22 , // 字体尺寸最小值
71
112
fontSizeMax : 26 , // 字体尺寸最大值
72
113
colors : [
@@ -109,16 +150,20 @@ export default class Vcode extends React.PureComponent<Props, State> {
109
150
}
110
151
111
152
/** 组件初始化完毕时触发 **/
112
- componentDidMount ( ) {
153
+ componentDidMount ( ) : void {
113
154
this . onDraw ( this . props . value ) ;
114
155
}
115
156
116
157
/** 组件参数改变 **/
117
- componentDidUpdate ( prevP : Props ) {
158
+ componentDidUpdate ( prevP : Props ) : void {
118
159
if ( this . props . value !== prevP . value ) {
119
160
this . onDraw ( this . props . value ) ;
120
161
}
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
+ ) {
122
167
this . setState ( {
123
168
width : this . props . width || 150 ,
124
169
height : this . props . height || 40 ,
@@ -131,7 +176,7 @@ export default class Vcode extends React.PureComponent<Props, State> {
131
176
}
132
177
133
178
/** 用户点击了验证码图片 **/
134
- onClick ( ) {
179
+ onClick ( ) : void {
135
180
// 如果用户没有设置值,就直接重新生成
136
181
if ( ! this . props . value ) {
137
182
this . onDraw ( this . props . value ) ;
@@ -147,8 +192,15 @@ export default class Vcode extends React.PureComponent<Props, State> {
147
192
*/
148
193
codeCss ( uW : number , i : number ) : string {
149
194
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
+ } `,
152
204
"position: absolute" ,
153
205
`left:${ this . randint ( uW * i , uW * i + uW - uW / 2 ) } px` ,
154
206
"top:50%" ,
@@ -157,7 +209,11 @@ export default class Vcode extends React.PureComponent<Props, State> {
157
209
`-ms-transform:rotate(${ this . randint ( - 15 , 15 ) } deg) translateY(-50%)` ,
158
210
`-moz-transform:rotate(${ this . randint ( - 15 , 15 ) } deg) translateY(-50%)` ,
159
211
`-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
+ } `,
161
217
"font-weight:bold" ,
162
218
"z-index:2" ,
163
219
] . join ( ";" ) ;
@@ -171,17 +227,34 @@ export default class Vcode extends React.PureComponent<Props, State> {
171
227
return [
172
228
"position: absolute" ,
173
229
`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`,
178
247
`top:${ this . randint ( 0 , this . state . height ) } px` ,
179
248
`transform:rotate(${ this . randint ( - 30 , 30 ) } deg)` ,
180
249
`-o-transform:rotate(${ this . randint ( - 30 , 30 ) } deg)` ,
181
250
`-ms-transform:rotate(${ this . randint ( - 30 , 30 ) } deg)` ,
182
251
`-moz-transform:rotate(${ this . randint ( - 30 , 30 ) } deg)` ,
183
252
`-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
+ } `,
185
258
`font-weight:${ this . randint ( 400 , 900 ) } ` ,
186
259
] . join ( ";" ) ;
187
260
}
@@ -190,33 +263,43 @@ export default class Vcode extends React.PureComponent<Props, State> {
190
263
* 绘制
191
264
* @param value 需要生成的字符值,不传则随机生成
192
265
* */
193
- onDraw ( value : string | undefined ) {
266
+ onDraw ( value : string | undefined ) : string | null {
194
267
let c = "" ; // 存储生成的code
195
268
const div = document . getElementById ( this . state . id ) ;
196
269
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
+ ) ; // 是否是图片
198
273
if ( div ) {
199
274
div . innerHTML = "" ;
200
275
}
201
276
202
277
if ( isImg ) {
203
278
// 用户传递了一张图片
204
279
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 ( ";" ) ;
206
285
dom . src = value as string ;
207
286
div && div . appendChild ( dom ) ;
208
287
this . props . onChange && this . props . onChange ( null ) ;
209
288
return null ;
210
289
}
211
290
212
291
// 不是图片而是普通字符串, 如果value存在说明是用户自定义的字符串
213
- let length = value ? value . length : this . state . len ; // 字符的长度
292
+ const length = value ? value . length : this . state . len ; // 字符的长度
214
293
215
294
const uW : number = this . state . width / length / 1.01 ; // 每个字符占的宽度
216
295
for ( let i = 0 ; i < length ; i ++ ) {
217
296
const dom = document . createElement ( "span" ) ;
218
297
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
+ ] ;
220
303
dom . innerHTML = String ( temp ) ;
221
304
c = `${ c } ${ temp } ` ;
222
305
div && div . appendChild ( dom ) ;
@@ -240,6 +323,13 @@ export default class Vcode extends React.PureComponent<Props, State> {
240
323
}
241
324
242
325
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
+ ) ;
244
334
}
245
335
}
0 commit comments