在這個(gè)前端不懂 React 就會(huì)被誤解成 low B 的時(shí)代恢筝,也只能苦逼的去學(xué)習(xí)一下咯嘶卧。 沒有學(xué)習(xí)過的可以轉(zhuǎn)到React官網(wǎng)或者React中文網(wǎng)。由于筆者也是沒有學(xué)幾天的初級(jí)選手怯伊,若有瞎說的地方吊档,忘斧正!
所有依賴包都是通過Gulp管理在孝,就不再贅述了诚啃。了解gulp請移步gulp 中文網(wǎng)。除此之外私沮,為了減少工作量以及驗(yàn)證反饋的美觀始赎,引入了一個(gè)amazeui的Input組件
首先引入自己依賴包
'use strict';
var React = require('react');
var AMR = require('amazeui-react');
var Input = AMR.Input;
然后開始寫自己的驗(yàn)證組件,我給他取名為 Captcha :
var Captcha = React.createClass({
propTypes: {
bgImage: React.PropTypes.string,
size: React.PropTypes.number,
captchaType: React.PropTypes.oneOf(['Calculation', 'Normal']),
color: React.PropTypes.string
},
通過 PropTypes 來指定并驗(yàn)證 Captcha 組件的屬性仔燕;在這里我規(guī)定了四個(gè)屬性造垛,都是不必須的(not required)。
bgImage:表示驗(yàn)證碼的背景圖片晰搀。
size:表示驗(yàn)證碼的長度(只在Normal下有效)五辽。
captchaType:表示驗(yàn)證類型,我這里寫了兩種外恕,一個(gè)字符串杆逗,一個(gè)簡單計(jì)算(即加減)。
color: 表示驗(yàn)證碼字母的顏色鳞疲。
然后開始初始化一部分屬性:
getDefaultProps: function() {
return {
size: 4,
captchaType: 'Normal'
};
},
同時(shí)設(shè)置 states 并初始化罪郊,在這里有三個(gè)狀態(tài)會(huì)發(fā)生變化,即驗(yàn)證碼內(nèi)容建丧,驗(yàn)證碼結(jié)果(結(jié)果和內(nèi)容好像是一起變的??)排龄,用戶輸入波势。
getInitialState: function(){
return {
expression: '',
validate: '',
validateInput: ''
};
},
expression: 表示驗(yàn)證碼的內(nèi)容(可能是如:“21-9”);
validate: 表示驗(yàn)證碼結(jié)果(如“12”)翎朱;
validateInput: 表示用戶輸入的結(jié)果橄维;
做到這一步了,就要開始想如何得到這個(gè) states 了拴曲,那么就要開始自定義一個(gè)生成驗(yàn)證碼的方法如下:(純屬自己瞎寫)
renderCode: function() {
//定義expression和result争舞,expression是字符串,result可能是字符串也可能是數(shù)字
var expression = '', result;
//判斷驗(yàn)證碼類型
if (this.props.captchaType == 'Calculation') {
result = 0;//計(jì)算類型則result為數(shù)字澈灼,初始化為0
//獲取隨機(jī)的兩個(gè)兩位數(shù)
var Calpre = Math.round(Math.random()*100);
var Calafter = Math.round(Math.random()*100);
var codeCal = ['-','+','x'];//運(yùn)算符
var i = Math.round(Math.random()*2);//獲得隨機(jī)運(yùn)算符
switch (codeCal[i]) {//判斷運(yùn)算符并計(jì)算
case '-':
expression = Calpre + '-' + Calafter;
result = Calpre - Calafter;
break;
case '+':
expression = Calpre + '+' + Calafter;
result = Calpre + Calafter;
break;
case 'x':
expression = Calpre + 'x' + Calafter;
result = Calpre * Calafter;
break;
}
} else if (this.props.captchaType == 'Normal'){
result = '';
var codeNormal = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';//字母庫
for (var i =0; i < this.porps.size; i ++) {
result = result + codeNormal[Math.round(Math.random()*(codeNormal.length-1))];
}//隨機(jī)獲取字母四個(gè)
expression = result.toLowerCase();//忽略大小寫
}
this.setState({//設(shè)置更新狀態(tài)
expression: expression,
validate: result
});
},
這樣設(shè)置玩了基本上就可以渲染組件了竞川,但是使用會(huì)發(fā)現(xiàn)剛進(jìn)來的時(shí)候驗(yàn)證碼生成方法 即 renderCode 也沒有觸發(fā),state并沒有發(fā)生改變叁熔,默認(rèn)expression為空委乌,顯示不出來驗(yàn)證碼。
這里我在組件初始化渲染之后(即componentDidMount)手動(dòng)觸發(fā)一次荣回。
componentDidMount: function() {
this.renderCode();
},
驗(yàn)證碼的生成做完了遭贸,接下來開始做用戶輸入和的校驗(yàn)。即在用戶輸入的時(shí)候 Input 發(fā)生改變的時(shí)候觸發(fā)心软,setState 改變 validateInput 這個(gè)狀態(tài)壕吹,重新渲染一次輸入框:
handleChange: function() {
this.setState({
validateInput: this.refs.field.getValue()
});
},
同時(shí)渲染之后要給用戶一個(gè)反饋,這里就用到了amazeui Input 組件的一個(gè)驗(yàn)證屬性validation删铃,它有三個(gè)值即success耳贬,error,warning猎唁,根據(jù)不同的值咒劲,不同的反饋,我們只需要判斷一下validateInput的值和result是否相等胖秒,若相等缎患,返回success,不相等返回error阎肝,如下:
validate: function() {
var thisInput = this.state.validateInput;
var validateCode = this.state.validate;
if (thisInput.toLowerCase() == validateCode.toString().toLowerCase()) {
return 'success';
} else if (thisInput != ''){
return 'error';
}
},
上面寫完之后就可以渲染整個(gè)組件了:
render: function() {
var inlineStyle = {
color: this.props.color,
backgroundImage: 'url(' + this.props.bgImage + ')'
};
return (
<div>
<Input
value={this.state.validateInput}
placeholder="請輸入驗(yàn)證碼"
validation={this.validate()}
ref="field"
onChange={this.handleChange} hasFeedback/>
<AMR.Button style={inlineStyle}
className="am-btn"
onClick={this.renderCode}>
{this.state.expression}</AMR.Button>
</div>
);
}
module.exports = Captcha;
演示結(jié)果如下(只能上圖了):
然后一個(gè)組件就這樣實(shí)現(xiàn)了挤渔,如果要在其他地方使用這個(gè)組件,只需要引入這個(gè)組件即可风题。
var Captcha = require(/dir/Captcha);
....
render: function() {
return (
<Captcha color="red" bgImage=".../xxx.png" captchaType="Calculation" size="4"/>
)
}
呃判导,就這樣可以了。