zoukankan      html  css  js  c++  java
  • React 进修之路(1)

    React

    React简介

    是由Facebook公司推广的一套框架,已经应用instagram等产品

    React就是为了提供应用程序性能而设计的一套框架

    angular中,对dom提供了一些指令,让dom具有一些功能,例如ng-repeatdom具有动态循环渲染的功能,ng-showdom元素具有动态显隐的功能等等

    比如将页面比作一辆汽车,

    Angular的实现就是为汽车添加一些装饰,增加一些功能,让汽车看上去很高大尚,这样势必要加大油门

    React的实现就是重新制造一辆汽车,是有四个轱辘,即可启动,不要很大的油门

      React有三大创新

        虚拟dom

        组件开发

        多端适配

          一处开发,处处适用

        react在0.13版本之后,做了一个处理

          将react文件分成了两个部分     

             React.js核心库文件(创建虚拟dom的,核心模块,写的应用程序可以兼容所有端)

             React-dom.js在浏览器端渲染虚拟dom

    创建虚拟dom

      由react对象提供的一个方法createElement

      第一个参数表示虚拟dom的名称,例如div

        有时我们还可以传递组件

      第二个参数是一个对象,表示虚拟dom中拥有的属性

        从第三个参数开始表示该虚拟dom元素的子元素

      子元素也要由createElement创建,但是文本节点可以直接写

      方法的返回值是一个虚拟domjs对象)

    Render

      由ReactDOM提供的一个方法

        三个参数

          1 渲染虚拟dom元素

          2 真实的dom元素

          3 渲染完成回调函数(不常用)

    1// 创建虚拟dom
    2var h1 = React.createElement(
    3        'h1', 
    4        {
    5            title: '这是标题'
    6        }, 
    7        '我是文本内容啦啦啦'
    8    )
    9// 将h1渲染到页面中
    10ReactDOM.render(h1, document.getElementById('app'), function () {
    11    console.log(arguments)
    12    console.log(this)
    })

    组件

      在react中定义的一个虚拟dom很难复用,所以通常我们将一组虚拟dom定义在组件中来复用

        createClass可以用来创建一个组件

      参数是一个对象,用来描述组件的

      可以在对象中定义render方法,通过返回值来渲染这组组件

      返回值,通常所有虚拟dom都在一个容器内

      组件式一个类,因此组件名称要以大写字母开头

      组件要想渲染到页面中,就要将组件转化成虚拟dom,通过React.createElement方法(由React-dom.js提供)

    1var List = React.createClass({
    2    // 通过render渲染页面
    3    render: function () {
    4        return (
    5             React.createElement(
    6                'ul', 
    7                null, 
    8                React.createElement('li', null, '六间房秀场'),
    9                React.createElement('li', null, '斗鱼TV'),
    10                React.createElement('li', null, '美女秀场'),
    11                React.createElement('li', null, '秀色直播')
    12            )
    13        )
    14    }
    15})
    16// 将组件渲染到页面中
    17// 转化组件到虚拟DOM
    18var ul = React.createElement(List)
    ReactDOM.render(ul, document.getElementById('app'))

    JSX语法

      我们写虚拟dom的最大问题,创建一个虚拟dom成本太高了(写的太麻烦了),React团队为了简化对createElement的书写,为我们提供了jsx语法

        react团队提供了两种处理方法

          第一种,在浏览器端编译 

              引入编译库,例如browser.js可以对jsx语法编译

              此时定义的script标签的type类型要定义成text/babel, 在里面可以写jsx语法

           第二种,在工程化中编译(最常见的)

              编译jsx语法,跟以前编译lesssassstylus很像

              首先要获取这些jsx文件(通常我们将写jsx语法的文件拓展名改成.jsx

      以fis为例

    1fis.match('**.jsx', {
    2    // 编译
    3    parser: 'babel2',
    4    // 更改后缀名称
    5    rExt: '.js'
    })

    特殊属性

    Class

      Classjs中是保留字,因此在react定义虚拟dom的时候,将class写成className

    For (是label元素特有的属性)

      Forjs中的关键字,因此在react定义虚拟dom的时候,将for属性写成htmlFor

    1var h1 = (<h1 className="red">我是文本内容啦啦啦</h1>);
    2// 将虚拟dom渲染到页面中
    3ReactDOM.render(h1, document.getElementById('app'))
    4
    5// 创建一个组件
    6var User = React.createClass({
    7    render: function() {
    8        // 返回虚拟dom
    9        return (
    10            <div>
    11                <label htmlFor="user_name">用户名</label>
    12                <input id="user_name" type="text" />
    13            </div>
    14        );
    15    }
    }) 

    插值

      React支持插值语法,我们在jsx语法中使用,语法是  {}

      一对{}提供了一个js环境,因此我们可以在大括号里面设置虚拟dom元素的属性,设置虚拟dom元素的内容

      我们可以在插值符号中使用js中的任何表达式

    非元素属性

      Key 为列表元素定义react-id,绑定id。这样可以方便获取页面中哪些元素更新了,哪些元素需要更新

      Render方法的作用域是组件实例化对象,可以访问到组件中定义的方法

    1createChildList: function () {
    2    // 遍历数组,处理每一个成员,然后映射一个新数组,就是map方法
    3    return data.map(function (value, index) {
    4        // 每一个li要绑定内容,还要设置key
    5        return <li key={index}>{value}</li>;
    6    })
    },

    属性

      在html中,对于同一类元素来说,之所以展现的样式不一样,是因为他们具有不同的属性,所以属性可以让同一类元素展现出不同的状态

      同样的道理,在react中,对于同一个组件来说,可以创建一组虚拟dom树,如果想让虚拟dom树展现出不同的状态,我们就要为其添加属性

      在虚拟dom上添加属性跟在html中元素上添加属性是一样的,通过添加一个属性实现(只不过在组件上添加的都是自定义属性)

      我们添加的自定义属性,会存储在组件的props属性中,我们通过this.props可以访问到里面的数据

      组件的默认属性我们定义在getDefaultProps中,通过返回值设置默认属性数据

    1// 创建导航标题组件
    2var Nav = React.createClass({
    3    // 定义默认属性数据
    4    getDefaultProps: function () {
    5        // 通过返回值定义默认属性数据
    6        return {
    7            data: ['默认标题']
    8        }
    9    },
    10    // 封装渲染内容的方法
    11    createChildList: function () {
    12        var me = this;
    13        // 遍历this.props.data渲染
    14        return this.props.data.map(function (value, index) {
    15            return (<a href="" key={index}>{value}{index != me.props.data.length - 1 ? '/' : ''}</a>)
    16        })
    17    },
    18    // 通过render方法渲染虚拟dom树
    19    render: function () {
    20        return (
    21            <div>
    22                {this.createChildList()}
    23            </div>
    24        )
    25    }
    26})
    27var data1 = ['财经', '证券', '理财'];
    28// 渲染
    ReactDOM.render(<Nav data={data1} />, document.getElementById('app'))

    样式

      在虚拟dom中我们可以为元素定义样式

      在react中,虚拟dom上不能使用行内样式字符串,行内样式只能定义成对象,Css属性名称如果出现多个单词,要使用驼峰式命名,例如

        border-color => borderColor

      还要求浏览器前缀第一个字母要大写,例如

        -webkit-box-shadow  => WebkitBoxShadow

      在createElement方法中,样式写在style中,直接赋值对象,jsx语法中,样式写在style中,要使用插值语法

    1// 定义虚拟dom
    2var h1 = React.createElement('h1', {
    3    style: {
    4        color: 'red',
    5        fontSize: '40px'
    6    }
    7}, '我是文本内容啦啦啦');
    8
    9// jsx语法,定义虚拟dom
    10var h1 = (<h1 style={{
    11    color: 'green',
    12    fontSize: '100px'
    }}>文本内容</h1>)

    事件

      React中定义事件,跟在html中定义事件很像

      在html中定义事件

        <button onclick="console.log('hello')">按钮</button>

      在reactjsx语法中定义事件,跟html中定义事件很像

        <button onClick={this.clickBtn}>按钮</button>

      on+事件名称=回调函数
        事件名称首字母大写

        事件回调函数通常绑定组件中的方法

        事件回调函数不要执行(后面不要加()

      事件回调函数

        作用域是组件实例化对象(可以通过this访问组件上的方法以及属性数据)

        可以通过bind方法更改作用域

        可以通过bind方法传递自定义参数(很少用)

      参数有三个

        React封装的事件对象(最常用)

        React-id

        源生的事件对象

    1var Demo = React.createClass({
    2    // 定义事件回调函数
    3    clickBtn: function () {
    4        console.log(arguments)
    5        console.log(this)
    6    },
    7    render: function () {
    8        return (
    9            <div>
    10                <button onClick={this.clickBtn.bind(this, 11)}>这是个按钮</button>
    11            </div>
    12        )
    13    }
    }) 

    这个就是参数

    状态

      状态跟属性一样都是在组件内部存储数据的

        属性是组件外部传递的数据

        状态是组件内部维护的数据

          有状态组件以及无状态组件

            无状态组件

              对于一个组件来说,如果组件没有状态,也就是说组件式一成不变的,组件在创建之后,不会发生交互,请求数据等等,这类组件叫无状态组件,

              组件自身不会维护状态

            有状态组件

              对于一个组件来说,自从创建以后,组件会产生一些交互,请求一些数据,来完成自身状态的更新,这类组件内部必须维护一个状态来存储这些变化的数据,这类组件叫有状态

        组件处于哪种状态由其自身存储的数据决定,组件的存储跟属性一样,在组件实例化对象中有个state属性,就是用来存储状态数据

        初始化状态用getInitialState方法定义,通过return 将初始化状态的数据返回

        修改状态,用setState方法

          参数是一个对象,对象中的属性就是即将修改的状态

        状态或者属性的改变都会触发render方法的执行,这句话很重要

    最后是一个小小的换肤案例

      html代码

    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title></title>
        <link rel="stylesheet" type="text/css" href="less/15.less">
    </head>
    <body>
        <div id="app"></div>
    <script type="text/javascript" src="lib/react.js"></script>
    <script type="text/javascript" src="lib/react-dom.js"></script>
    <script type="text/javascript" src="lib/jquery.js"></script>
    <script type="text/javascript" src="code/15.jsx"></script>
    </body>
    </html>

      less代码

    * {
        list-style: none;
        margin: 0;
        padding: 0;
    }
    body {
        background-repeat: no-repeat;
        background-attachment: fixed;
        background-position: center 0;
        background-size: cover;
    }
    #app {
         1118px;
        margin: 50px auto;
        ul {
            margin-right: -10px;
        }
        li {
             178px;
            margin-right: 10px;
            float: left;
            margin-bottom: 10px;
        }
        p {
            line-height: 30px;
            text-align: center;
        }
        img {
            cursor: pointer;
        }
    }

      jsx代码

    // 定义换肤组件
    var Skin = React.createClass({
        // 初始化状态数据
        getInitialState: function () {
            return {
                list: []
            }
        },
        // 定义事件回调函数
        chooseImage: function (e) {
            // 获取li元素
            var li = e.currentTarget;
            // 获取
            var id = li.getAttribute('data-id')
            // 用id获取大图片的地址,渲染body
            document.body.style.backgroundImage = 'url(img/skin/big_' + id + '.jpg)'
            // console.log(id)
        },
        // 定义渲染列表的方法
        getImageList: function () {
            var me = this;
            // 通过状态来渲染了
            return this.state.list.map(function (obj, index) {
                return (<li key={index} data-id={obj.id} onClick={me.chooseImage}>
                        <img src={"img/skin/" + obj.src} alt=""/>
                        <p>{obj.title}</p>
                    </li>)
            })
        },
        render: function () {
            return (
                <ul>{this.getImageList()}</ul>
            )
        },
        // 发送请求获取数据
        componentDidMount: function () {
            var me = this;
            $.get('data/skin.json', function (res) {
                // 请求成功,更新状态数据
                if (res && res.errno === 0) {
                    me.setState({
                        list: res.data
                    })
                }
            })
        }
    })    
    
    // 渲染到页面中
    ReactDOM.render(<Skin />, document.getElementById('app'))
  • 相关阅读:
    《应用Yii1.1和PHP5进行敏捷Web开发》学习笔记(转)
    YII 小模块功能
    Netbeans代码配色主题大搜集
    opensuse 启动巨慢 解决方法 90s多
    opensuse 安装 网易云音乐 rpm netease music
    linux qq rpm deb opensuse
    openSUSE 安装 alien
    第一行代码 Android 第2版
    Android Studio AVD 虚拟机 联网 失败
    docker error during connect: Get http://%2F%2F.%2Fpipe%2Fdocker_engine/v1.29/containers/json: open //./pipe/docker_engine: The system cannot find the file specified. In the default daemon configuratio
  • 原文地址:https://www.cnblogs.com/bandeng/p/6550479.html
Copyright © 2011-2022 走看看