React 實(shí)現(xiàn)一個(gè)驗(yàn)證碼組件

在這個(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é)果如下(只能上圖了):

乘法
字母
錯(cuò)誤
加法

然后一個(gè)組件就這樣實(shí)現(xiàn)了挤渔,如果要在其他地方使用這個(gè)組件,只需要引入這個(gè)組件即可风题。

var Captcha = require(/dir/Captcha);

....

render: function() {
    return (
        <Captcha color="red" bgImage=".../xxx.png" captchaType="Calculation" size="4"/>
    )
}

呃判导,就這樣可以了。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末沛硅,一起剝皮案震驚了整個(gè)濱河市眼刃,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌摇肌,老刑警劉巖擂红,帶你破解...
    沈念sama閱讀 206,214評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異围小,居然都是意外死亡昵骤,警方通過查閱死者的電腦和手機(jī)树碱,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來变秦,“玉大人成榜,你說我怎么就攤上這事”拿担” “怎么了赎婚?”我有些...
    開封第一講書人閱讀 152,543評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵,是天一觀的道長樱溉。 經(jīng)常有香客問我挣输,道長,這世上最難降的妖魔是什么福贞? 我笑而不...
    開封第一講書人閱讀 55,221評(píng)論 1 279
  • 正文 為了忘掉前任歧焦,我火速辦了婚禮,結(jié)果婚禮上肚医,老公的妹妹穿的比我還像新娘绢馍。我一直安慰自己,他們只是感情好肠套,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,224評(píng)論 5 371
  • 文/花漫 我一把揭開白布舰涌。 她就那樣靜靜地躺著,像睡著了一般你稚。 火紅的嫁衣襯著肌膚如雪瓷耙。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,007評(píng)論 1 284
  • 那天刁赖,我揣著相機(jī)與錄音搁痛,去河邊找鬼。 笑死宇弛,一個(gè)胖子當(dāng)著我的面吹牛鸡典,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播枪芒,決...
    沈念sama閱讀 38,313評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼彻况,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了舅踪?” 一聲冷哼從身側(cè)響起纽甘,我...
    開封第一講書人閱讀 36,956評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎抽碌,沒想到半個(gè)月后悍赢,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,441評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,925評(píng)論 2 323
  • 正文 我和宋清朗相戀三年左权,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了瞒斩。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,018評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡涮总,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出祷舀,到底是詐尸還是另有隱情瀑梗,我是刑警寧澤,帶...
    沈念sama閱讀 33,685評(píng)論 4 322
  • 正文 年R本政府宣布裳扯,位于F島的核電站抛丽,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏饰豺。R本人自食惡果不足惜亿鲜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,234評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望冤吨。 院中可真熱鬧蒿柳,春花似錦、人聲如沸漩蟆。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽怠李。三九已至圾叼,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間捺癞,已是汗流浹背夷蚊。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評(píng)論 1 261
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留髓介,地道東北人惕鼓。 一個(gè)月前我還...
    沈念sama閱讀 45,467評(píng)論 2 352
  • 正文 我出身青樓,卻偏偏與公主長得像唐础,于是被迫代替她去往敵國和親呜笑。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,762評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,500評(píng)論 25 707
  • 項(xiàng)目整體設(shè)計(jì)為前后端完全分離的模式彻犁,前端采用react以及amazeui構(gòu)建用戶交互界面叫胁,后端采用python f...
    arcsecw閱讀 1,437評(píng)論 0 2
  • 現(xiàn)在最熱門的前端框架,毫無疑問是 React 汞幢。上周驼鹅,基于 React 的 React Native 發(fā)布,結(jié)果一...
    sakura_L閱讀 419評(píng)論 0 0
  • 做夢夕陽下 ■田秀 和風(fēng)一起張揚(yáng)在夕陽下 和誰緩緩而...
    巴山雪兒閱讀 244評(píng)論 0 2
  • 這是一個(gè)有些久遠(yuǎn)的故事,遠(yuǎn)到每次我們提起它输钩,就像是在一間破爛豺型,充滿揮之不去,嗆人霉味的老屋子的閣樓上买乃,聽著活了很久...
    砂蔚閱讀 456評(píng)論 3 7