Skip to content

Commit 974043c

Browse files
committed
globalObject配置,支持服务端渲染 / 其他包版本更新
1 parent 673596b commit 974043c

File tree

5 files changed

+133
-35
lines changed

5 files changed

+133
-35
lines changed

example/src/index.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ class Test extends React.Component {
6464
<div>
6565
<div>
6666
<input type="text" placeholder="请输入正确的验证码" value={this.state.input2} onChange={e => this.onInput2Change(e)} maxLength={20} />
67-
<Vcode onChange={v => this.onVcode2Change(v)} value={this.state.code} width={this.state.width} />
67+
<Vcode onChange={v => this.onVcode2Change(v)} onClick={() => console.log('触发onClick') } value={this.state.code} width={this.state.width} />
6868
<span>{this.state.input2 === this.state.vcode2 ? "输入正确" : "输入错误"}</span>
6969
</div>
7070
<hr />

package.json

+17-11
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "react-vcode",
3-
"version": "1.0.8",
3+
"version": "1.0.10",
44
"description": "a react verification code component",
55
"main": "dist/index.js",
66
"files": [
@@ -9,7 +9,8 @@
99
"scripts": {
1010
"dev": "webpack-dev-server --config webpack.config.js",
1111
"build:babel": "babel src -d lib",
12-
"build": "webpack --config webpack.build.config.js --progress --profile --colors"
12+
"build": "webpack --config webpack.build.config.js --progress --profile --colors",
13+
"prettier": "prettier --write \"src/index.tsx\""
1314
},
1415
"types": "dist/index.d.ts",
1516
"typings": "dist/index.d.ts",
@@ -33,25 +34,30 @@
3334
"react-dom": "^16.13.1"
3435
},
3536
"devDependencies": {
36-
"@babel/cli": "^7.10.5",
37-
"@babel/core": "^7.11.4",
37+
"@babel/cli": "^7.11.6",
38+
"@babel/core": "^7.11.6",
3839
"@babel/plugin-proposal-decorators": "^7.10.5",
39-
"@babel/plugin-transform-runtime": "^7.11.0",
40-
"@babel/preset-env": "^7.11.0",
40+
"@babel/plugin-transform-runtime": "^7.11.5",
41+
"@babel/preset-env": "^7.11.5",
4142
"@babel/preset-react": "^7.10.4",
4243
"@babel/runtime": "^7.11.2",
43-
"@types/react": "^16.9.48",
44+
"@types/react": "^16.9.49",
4445
"@types/react-dom": "^16.9.8",
46+
"@typescript-eslint/eslint-plugin": "^4.1.0",
47+
"@typescript-eslint/parser": "^4.1.0",
4548
"autoprefixer": "^9.8.6",
4649
"awesome-typescript-loader": "^5.2.1",
4750
"babel-loader": "^8.1.0",
48-
"css-loader": "^4.2.2",
49-
"eslint": "^7.7.0",
51+
"css-loader": "^4.3.0",
52+
"eslint": "^7.8.1",
5053
"eslint-config-prettier": "^6.11.0",
5154
"eslint-loader": "^4.0.2",
5255
"eslint-plugin-prettier": "^3.1.4",
53-
"file-loader": "^6.0.0",
54-
"source-map-loader": "^1.0.2",
56+
"eslint-plugin-react": "^7.20.6",
57+
"eslint-plugin-react-hooks": "^4.1.0",
58+
"file-loader": "^6.1.0",
59+
"prettier": "^2.1.1",
60+
"source-map-loader": "^1.1.0",
5561
"style-loader": "^1.2.1",
5662
"typescript": "^4.0.2",
5763
"url-loader": "^4.1.0",

src/index.tsx

+113-23
Original file line numberDiff line numberDiff line change
@@ -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
}
1618
interface 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 = /^http[s]*:\/\/|\.jpg$|\.png$|\.jpeg$|\.gif$|\.bmp$|\.webp$|^data:image/.test(value || ""); // 是否是图片
270+
const isImg: boolean = /^http[s]*:\/\/|\.jpg$|\.png$|\.jpeg$|\.gif$|\.bmp$|\.webp$|^data:image/.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
}

tsconfig.json

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
"noImplicitReturns": true,
1616
"noImplicitAny": false,
1717
"noFallthroughCasesInSwitch": true,
18+
1819
"outDir": "dist",
1920
"lib": ["es2018", "dom"]
2021
},

webpack.build.config.js

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ module.exports = {
1515
filename: "[name].js",
1616
library: "vcode",
1717
libraryTarget: "umd",
18+
globalObject: 'this'
1819
//libraryExport: 'default',
1920
},
2021
externals: {

0 commit comments

Comments
 (0)