软件世界网 购物 网址 三丰软件 | 小说 美女秀 图库大全 游戏 笑话 | 下载 开发知识库 新闻 开发 图片素材
多播视频美女直播
↓电视,电影,美女直播,迅雷资源↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
移动开发 架构设计 编程语言 Web前端 互联网
开发杂谈 系统运维 研发管理 数据库 云计算 Android开发资料
  软件世界网 -> Web前端 -> ReactJS学习笔记(二) -> 正文阅读

[Web前端]ReactJS学习笔记(二)



我们终要远行,最终告别稚嫩的自己。

使用React来构建web应用,每个页面都将是多个组件组成,并且相互嵌套来构成的,接下来就学习下组件的嵌套。

一、组件嵌套:


背景交代:
1、创建一个html,包含引用的相关js、需要被渲染的div;
2、创建一个有label与input标签组成的简单组件 — IvanInput,并可以通过传入数组来渲染多组label与input标签,拥有不同的label名称、inputType、inputRef、inputName及input的onChange事件;
3、创建一个button与a标签组成的简单组件 — IvanButton,并可以通过传入的数组来渲染一组button与啊标签,拥有不同的buttonName、button的onClick事件、a标签名称、a标签的onClick事件;
4、创建一个IvanPage组件,包含一个h1标签、多个IvanInput组件、一个IvanButton组件。

1、创建一个html,名称随便起哈:
<!DOCTYPE html>
<html>
<head lang="en">
    <!--设置为utf-8防止中文乱码-->
    <meta charset="UTF-8">
    <title></title>
    <script src="../../dist/react/react.js"></script>
    <script src="../../dist/react/JSXTransformer.js"></script>
    <script src="../../dist/jquery/jquery.min.js"></script>
    <!--如下的这种引用方式是不正确的,必须使用上面的引用方式-->
    <!--<script src="../../dist/react/JSXTransformer.js"/>-->
    <!--自定义的js文件路径-->
    <script type="text/jsx" src="../../js/react/ivanPage.js"></script>
    <!--简单的样式可以忽略不计-->
    <style>
        body{TEXT-ALIGN: center;}
        #index-0329-0041{ MARGIN-RIGHT: auto;
            MARGIN-LEFT: auto;
            height:200px;
            width:400px;
            vertical-align:middle;
        }
    </style>
</head>
<body>
<!--需要被渲染的div,id与自定义的css样式一致即可-->
<div id="index-0329-0041"></div>
<script type="text/jsx">
    /*你的js代码块*/
</script>
</body>
</html>

2、创建一个js文件(步骤1中引用的IvanPage.js),并在js中创建IvanInput组件:
var IvanInput = React.createClass({
    //渲染DOM,相当于java的main函数
    render: function () {
        return (
            <div>
                <label>用户名:</label>
                <input type='text' ref='userName' name=userName onChange=this.textOnChange()/>
            </div>
        );
    }
});

为了使组件可以复用,并符合背景交代中的第二条,我需要将label名称、input标签的type、ref、name及onChange事件使用props参数的形式传递给IvanInput组件,更新上方代码为:
var IvanInput = React.createClass({
    //渲染DOM,相当于java的main函数
    render: function () {
        return (
            <div>
                <label>{this.props.labelName}:</label>
                <input type={this.props.inputType} ref={this.props.inputRef} name={this.props.inputName} onChange={this.props.onChangeMethod}/>
            </div>
        );
    }
});

如果想使用IvanInput组件,你就必须给我传递过来以下参数:labelName、inputType、inputRef、inputName、onChangeMethod(这是一个方法),即:
React.render(
        <IvanInput labelName = '用户名' inputType='text' inputRef='userName' inputName='userName' onChangeMethod={方法}/>,
        document.getElementById('被渲染的id')
    );

3、同理,继续在此js文件中创建另一个组件IvanButton:
var IvanButton = React.createClass({
    render: function () {
        return (
            <div>
                <button onClick={this.props.buttonClickMethod} >{this.props.buttonName}</button>
                <a onClick={this.props.aHrefClick}>{this.props.aName}</a>
            </div>
        );
    }
});

如果要使用IvanButton组件,需要传递以下参数:buttonClickMethod(这是一个方法)、buttonName(button名称)、aHref(这是一个方法)、aName(a标签名称),即:
React.render(
        <IvanButton buttonName='登录' buttonClickMethod={button的点击事件}
                            aName='忘记密码?' aHrefClick={a标签的点击事件}/>,
        document.getElementById('被渲染的id')
    );

4、继续在js中创建IvanPage组件,并对IvanInput及IvanButton两个组件进行调用:
根据2、3步骤中的调用方式,需要建立3个方法(onSubmit:button的点击事件、textOnChange:文本框方式变化事件、aHrefClick:a标签的onClick事件),同时希望h1标签的值是通过参数的方式传递过来的。
var IvanPage = React.createClass({
    //button的点击事件
    onSubmit:function(){
        console.log('onSubmit被点击了');
    },

    //文本框的点击事件
    textOnChange: function (e) {
        console.log('文本信息发生变化');
        //TODO 处理相关验证任务
    },

    //a标签的点击事件
    aHrefClick: function () {
        console.log('a标签被点击');
    },

    render: function () {
        return(
            <div>

                <h1>{this.props.titleName}</h1>
                <IvanInput labelName = '用户名' inputType='text' inputRef='userName' inputName='userName' onChangeMethod={this.textOnChange}/>
                <IvanButton buttonName='提交' buttonClickMethod={this.onSubmit}
                            aName='忘记密码?' aHrefClick={this.aHrefClick}/>
            </div>

        );
    }
});

调用IvanPage,并传递参数titleName,更新步骤1中的html代码如下:
<script type="text/jsx">
    /*你的js代码块*/
    React.render(
        <IvanPage titleName="登录页面" />,
        document.getElementById('index-0329-0041')
    );
</script>

运行下你的html文件吧,并点击“提交”、“忘记密码?”、文本框输入相关数值查看控制台输出吧,效果如下:
[img]http://img.blog.csdn.net/20160331104933184
5、登录!登录!登录!特么就一个用户名搞啥子哟?对的,需要一个“密码”!由于密码与用户名的本质区别就是label与input不同,而我们的IvanInput组件只有label与input两个标签,并可以通过传递不同的参数来展示不同的DOM,那么问题就简单了,拷贝一份IvanInput的调用即可。
更新IvanPage组件,重复调用IvanInput组件(参数不同),还需要为密码框创建一个单独的点击事件pwdOnChange:
var IvanPage = React.createClass({
    //button的点击事件
    onSubmit:function(){
        console.log('onSubmit被点击了');
    },

    //文本框的点击事件
    textOnChange: function (e) {
        console.log('文本信息发生变化');
        //TODO 处理相关验证任务
    },

    //密码框的点击事件
    pwdOnChange: function (e) {
        console.log('密码信息发生变化');
        //TODO 处理相关验证任务
    },

    //a标签的点击事件
    aHrefClick: function () {
        console.log('a标签被点击');
    },

    render: function () {
        return(
            <div>
                <h1>{this.props.titleName}</h1>
                <IvanInput labelName = '用户名' inputType='text' inputRef='userName' inputName='userName' onChangeMethod={this.textOnChange}/>
                <IvanInput labelName = '密码' inputType='password' inputRef='userPwd' inputName='userPwd' onChangeMethod={this.pwdOnChange}/>
                <IvanButton buttonName='提交' buttonClickMethod={this.onSubmit}
                            aName='忘记密码?' aHrefClick={this.aHrefClick}/>
            </div>

        );
    }
});

运行下步骤1中的html文件,是不是多了个密码框?这才是登录页面嘛!
[img]http://img.blog.csdn.net/20160331105741094

问题:
虽然实现了组件的嵌套调用,但这样的IvanPage组件样式及内容已经完全固定,无法更改,这就没办法复用组件,改如何解决呢?

6、要解决上面提出的问题,就需要在最外层传递参数,也就是html里进行参数的传递,通过不同的参数来影响IvanPage页面的内容及样式信息。
  • 定义inputdata/otherdata数组,存放渲染IvanInput/IvanButton组件的必要参数信息,将inputdata与otherdata参数传递给IvanPage组件,更新html中的代码:
<script type="text/jsx">
    /*你的js代码块*/
    var inputdata = [
        {enable:false,labelName:'用户名',inputType:'text',inputRef:'userName',inputName:'userName',method:0},
        {enable:false,labelName:'密码',inputType:'password',inputRef:'userPwd',inputName:'userPwd',method:1}
    ];

    var otherdata = {buttonName:'登录',titleName:'登录界面',aName:'忘记密码?'};

    React.render(
            <IvanPage inputdata={inputdata} otherdata={otherdata}/>,
            document.getElementById('index-0329-0041')
    );
</script>
  • 接收传递的props数据,并存入state中,更新js中的IvanPage组件,加入初始化方法getInitialState,进行数据的接收,并分别命名为inputdata及otherdata:
getInitialState: function () {
        return {inputdata:this.props.inputdata,otherdata:this.props.otherdata}
    }
  • 遍历inputdata数组,进行批量渲染IvanInput组件,获取otherdata数组中的数据,并传递给IvanButton组件。
render: function () {
        {
            var onChangeMethod = [this.textOnChange,this.pwdOnChange];
            //优先生成多个Input组件
            var IvanInputs =  this.state.inputdata.map(function(d){
                return(
                    //查看官方文档,使用map时需定义一个key变量
                    <IvanInput key={d.inputType} labelName = {d.labelName} inputType={d.inputType} inputRef={d.inputRef}
                               inputName={d.inputName} onChangeMethod={onChangeMethod[d.method]}/>
                );
            });
        }
        return(
            <div>
                <h1>{this.state.otherdata.titleName}</h1>
                {IvanInputs}
                <IvanButton buttonName={this.state.otherdata.buttonName} buttonClickMethod={this.onSubmit}
                            aName={this.state.otherdata.aName} aHrefClick={this.aHrefClick}/>
            </div>

        );
    }

完整代码请见最后。。。
至此,组件的嵌套就搞完了,其实也搞定了组件的复用,怎么复用这些组件呢?

二、组件的复用


可以使用如下的两种方式进行组件的复用:
1、最简单的办法,就是在拷贝上面的html文件,更改html文件中的数组信息,即可实现组件的复用了,例如:
<!DOCTYPE html>
<html>
<head lang="en">
    <!--设置为utf-8防止中文乱码-->
    <meta charset="UTF-8">
    <title></title>
    <script src="../../dist/react/react.js"></script>
    <script src="../../dist/react/JSXTransformer.js"></script>
    <script src="../../dist/jquery/jquery.min.js"></script>
    <!--如下的这种引用方式是不正确的,必须使用上面的引用方式-->
    <!--<script src="../../dist/react/JSXTransformer.js"/>-->
    <!--自定义的js文件路径-->
    <script type="text/jsx" src="../../js/react/IvanPage-csdn.js"></script>
    <!--简单的样式可以忽略不计-->
    <style>
        body{TEXT-ALIGN: center;}
        #index-0329-0042{ MARGIN-RIGHT: auto;
            MARGIN-LEFT: auto;
            height:200px;
            width:400px;
            vertical-align:middle;
        }
    </style>
</head>
<body>
<!--需要被渲染的div,id与自定义的css样式一致即可-->
<div id="index-0329-0042"></div>
<script type="text/jsx">
    /*你的js代码块*/
    var inputdata = [
        {enable:false,labelName:'邮箱',inputType:'email',inputRef:'userEmail',inputName:'userEmail',method:0},
        {enable:false,labelName:'验证码',inputType:'text',inputRef:'authCode',inputName:'authCode',method:1}
    ];

    var otherdata = {buttonName:'找回密码',titleName:'找回密码',aName:'发送验证码'};

    React.render(
            <IvanPage inputdata={inputdata} otherdata={otherdata}/>,
            document.getElementById('index-0329-0042')
    );
</script>
</body>
</html>

运行效果如下:
[img]http://img.blog.csdn.net/20160331112233338
2、通过相关事件来更改state中的参数值,ReactJS会自动的重新渲染整个页面完成组件的复用,那么就在a标签的点击事件中来简单的尝试一下吧!
更新IvanPage组件中的aHrefClick方法:
 aHrefClick: function () {
        console.log('a标签被点击');
        if(this.state.otherdata.aName == '忘记密码?'){
            var inputdata = [
                {enable:false,labelName:'邮箱',inputType:'email',inputRef:'userEmail',inputName:'userEmail',method:0},
                {enable:false,labelName:'验证码',inputType:'text',inputRef:'authCode',inputName:'authCode',method:1}
            ];

            var otherdata = {buttonName:'验证',titleName:'找回密码',aName:'发送验证码'};

            this.setState({inputdata:inputdata,otherdata:otherdata});
        }else{
            //TODO something
        }
    },

这时候点击登录页面的“忘记密码?”时,页面将被ReactJS重新渲染成一个新的DOM,就完成了组件的复用功能,是不是很屌的样子,其实人家ReactJS本来就很屌的。

3、完整代码:

  • html
<!DOCTYPE html>
<html>
<head lang="en">
    <!--设置为utf-8防止中文乱码-->
    <meta charset="UTF-8">
    <title></title>
    <script src="../../dist/react/react.js"></script>
    <script src="../../dist/react/JSXTransformer.js"></script>
    <script src="../../dist/jquery/jquery.min.js"></script>
    <!--如下的这种引用方式是不正确的,必须使用上面的引用方式-->
    <!--<script src="../../dist/react/JSXTransformer.js"/>-->
    <!--自定义的js文件路径-->
    <script type="text/jsx" src="../../js/react/ivanPage.js"></script>
    <!--简单的样式可以忽略不计-->
    <style>
        body{TEXT-ALIGN: center;}
        #index-0329-0041{ MARGIN-RIGHT: auto;
            MARGIN-LEFT: auto;
            height:200px;
            width:400px;
            vertical-align:middle;
        }
    </style>
</head>
<body>
<!--需要被渲染的div,id与自定义的css样式一致即可-->
<div id="index-0329-0041"></div>
<script type="text/jsx">
    /*你的js代码块*/
    var inputdata = [
        {enable:false,labelName:'用户名',inputType:'text',inputRef:'userName',inputName:'userName',method:0},
        {enable:false,labelName:'密码',inputType:'password',inputRef:'userPwd',inputName:'userPwd',method:1}
    ];

    var otherdata = {buttonName:'登录',titleName:'登录界面',aName:'忘记密码?'};

    React.render(
            <IvanPage inputdata={inputdata} otherdata={otherdata}/>,
            document.getElementById('index-0329-0041')
    );
</script>
</body>
</html>
  • ivanPage.js
/**
 * Created by ivan on 2016/3/31.
 */

/*
 定义组件(首字母比较大写),相当于java中的类的声明
 */
var IvanInput = React.createClass({
    //渲染DOM,相当于java的main函数
    render: function () {
        return (
            <div>
                <label>{this.props.labelName}:</label>
                <input type={this.props.inputType} ref={this.props.inputRef} name={this.props.inputName} onChange={this.props.onChangeMethod}/>
            </div>
        );
    }
});

var IvanButton = React.createClass({
    render: function () {
        return (
            <div>
                <button onClick={this.props.buttonClickMethod} >{this.props.buttonName}</button>
                <a onClick={this.props.aHrefClick}>{this.props.aName}</a>
            </div>
        );
    }
});

var IvanPage = React.createClass({
    //button的点击事件
    onSubmit:function(){
        console.log('onSubmit被点击了');
    },

    //文本框的点击事件
    textOnChange: function (e) {
        console.log('文本信息发生变化');
        //TODO 处理相关验证任务
    },

    //密码框的点击事件
    pwdOnChange: function (e) {
        console.log('密码信息发生变化');
        //TODO 处理相关验证任务
    },

    //a标签的点击事件
    aHrefClick: function () {
        console.log('a标签被点击');
        if(this.state.otherdata.aName == '忘记密码?'){
            var inputdata = [
                {enable:false,labelName:'邮箱',inputType:'email',inputRef:'userEmail',inputName:'userEmail',method:0},
                {enable:false,labelName:'验证码',inputType:'text',inputRef:'authCode',inputName:'authCode',method:1}
            ];

            var otherdata = {buttonName:'验证',titleName:'找回密码',aName:'发送验证码'};

            this.setState({inputdata:inputdata,otherdata:otherdata});
        }
    },

    getInitialState: function () {
        return {inputdata:this.props.inputdata,otherdata:this.props.otherdata,firstParam:'',secondParam:''}
    },

    render: function () {
        {
            var onChangeMethod = [this.textOnChange,this.pwdOnChange];
            //优先生成多个Input组件
            var IvanInputs =  this.state.inputdata.map(function(d){
                return(
                    //查看官方文档,使用map时需定义一个key变量
                    <IvanInput key={d.inputType} labelName = {d.labelName} inputType={d.inputType} inputRef={d.inputRef}
                               inputName={d.inputName} onChangeMethod={onChangeMethod[d.method]}/>
                );
            });
        }
        return(
            <div>
                <h1>{this.state.otherdata.titleName}</h1>
                {IvanInputs}
                <IvanButton buttonName={this.state.otherdata.buttonName} buttonClickMethod={this.onSubmit}
                            aName={this.state.otherdata.aName} aHrefClick={this.aHrefClick}/>
            </div>

        );
    }
});


......显示全文...
    点击查看全文


上一篇文章      下一篇文章      查看所有文章
2016-04-01 16:48:17  
Web前端 最新文章
10分钟
SSM框架SSM项目源码SSM源码下载java框架整合
javascript入门
JavaScript常用对象Array(2)
8.Smarty3:模版中的内置函数
表单脚本
iTextSharp5.0页眉页脚及Asp.net预览的实现
MVC基础学习—理论篇
JavaScript
http协议中get与post区别详解
360图书馆 软件开发资料 文字转语音 购物精选 软件下载 美食菜谱 新闻资讯 电影视频 小游戏 Chinese Culture
生肖星座 三丰软件 视频 开发 Android开发 站长 古典小说 网文精选 搜图网 美图 中国文化英文版 多播 租车 短信
2017-7-25 20:43:41
多播视频美女直播
↓电视,电影,美女直播,迅雷资源↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  软件世界网 --