React 進修之路(1)

React

React簡介javascript

是由Facebook公司推廣的一套框架,已經應用instagram等產品css

React就是爲了提供應用程序性能而設計的一套框架html

angular中,對dom提供了一些指令,讓dom具備一些功能,例如ng-repeatdom具備動態循環渲染的功能,ng-showdom元素具備動態顯隱的功能等等java

好比將頁面比做一輛汽車,react

Angular的實現就是爲汽車添加一些裝飾,增長一些功能,讓汽車看上去很高大尚,這樣勢必要加大油門jquery

React的實現就是從新制造一輛汽車,是有四個軲轆,便可啓動,不要很大的油門web

  React有三大創新json

    虛擬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 {
    width: 1118px;
    margin: 50px auto;
    ul {
        margin-right: -10px;
    }
    li {
        width: 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'))
相關文章
相關標籤/搜索