1. 程式人生 > >React結合es6例項教程

React結合es6例項教程

前言        

        本文主要是關於webpack+es6+react的基礎頁面例項的講解,通過這個簡單的單頁面的講解,當掌握單頁面的用法後,實現具體專案是也就是通過控制檯呼叫不同的頁面,本文為基礎帖到實戰帖的過度,適合有react基礎的小夥伴,大神請繞行哦。

        ok我們廢話不多講直接上圖,先給大家看下完成後的效果圖,是不是很醜,沒關係啦!懂得原理剩下的交給css去做啦,什麼配色呀,圖片新增呀,大多都是ui的事情,你都懂了不就是搶了別人飯碗了嗎,不過吧有一個好的頁面鑑賞和規劃能力也是必不可少的,但是大家都是菜鳥就不拘小節一下下啦,忍住往下看。


 頁面整體

        使用react製作頁面時,我覺得吧應該從對頁面劃分開始

,那麼我就先簡單的對頁面進行劃分,其中head和foot主要是為了讓大家更好的體會關於頁面模組化,在本頁面中並沒有什麼卵用,它們會在本鳥後續的部落格中體現自己的威力。


        圖中可以看出頁面是由三層巢狀關係也就是程式碼中的巢狀,綠色的是爺爺輩,紅色自然就是兒子啦,小藍就是孫子啦,我們發現爺爺有三個兒子,分別是header、ItemPanel、Footer,只有ItemPanel到了結婚年紀了生下了小藍Item,因此js之間的關係也就非常明瞭了,然後我們去看下面的實現過程。

頁面容器App.js

        在爺爺輩的App.js中通過import引入自己的三個兒子,注意import不是react特有的方法

,他和export以及class都是es6中新增的,這個超級爽如果熟悉java的小夥辦就會覺得超級熟悉有沒有,定義方法和使用規則簡直和java一樣有沒有,我們針對任意一個引入進行講解:import Header from  './Header.js';就是引入同級目錄下的Header.js檔案並且起了個別名叫個Header,這個用處就是在後續的render()函式中當做標籤使用,並且可以在<Header/>標籤中新增屬性,通過屬性props可以進行資料流傳遞。

import './App.css';
import React from 'react';

import Header from './Header.js';
import ItemPanel from './ItemPanel.js';
import Footer from './Footer.js';
import Store from './Store.js';

class App extends React.Component {
    constructor(props){
        super(props);
        this.state={
            store:new Store

        }
    }
    removeItem=(key)=>{
        //對狀態進行修改
        this.setState({
            store:this.state.store.removeItem(key)
        });
    }
    render(){
        return (
            <div>
                <Header/>
                <ItemPanel items={this.state.store.store} removeItem={this.removeItem}/>
                <Footer/>
            </div>
        );
    }
}

export default App;

跳過Footer和Header直接奔向最爭氣的小兒子ItemPanel    

        因為Footer和Header實在沒什麼好說的,因此接下來出場的就是ItemPanel他們一家人了,也是根據程式碼來看看,通用的引入,在這裡有必要簡單的說下這個export了,export其實是講構建好的模板進行丟擲,讓其他js進行引用,最頂層的是可以不需要這個東西的。除此之外他有很多種丟擲方式,export一個完整的class、單獨丟擲方法或者變數,具體細節不熟悉的小夥伴可以自行百度,看看大神的解釋。細心的夥伴一定發現了,爺爺頭上也有這個東西,那是因為我這裡使用了create-react-app進行腳手架搭建,為了方便直接把它拋給了index.js,也就是說你寫的這個頁面,只要想被別人應用都可以通過加上export進行丟擲,這風格有點像seajs中的寫法,當然這也是es6的一大亮點,添加了類似與seajs等前端的模組化載入框架的功能。

import React from 'react';
import Item from './Item.js';
export default class ItemPanel extends React.Component{
    constructor(props){
        super(props);
    }
	render(){
	    let items = [];
	    if(this.props.items && this.props.items.length!=0){
                this.props.items.forEach((item,index) => {
                    items.push(<Item item={item} index={index} key={item.key} removeItem={this.props.removeItem}/>);
                });
	    }else{
                items.push(<tr><th colSpan="5" className="tempEmpty">暫無使用者</th></tr>);
            }
		return (
		  <table className='itemPanel'>
		    <thead>
			    <th className='itemTd'>姓名</th>
				<th className='itemTd'>年齡</th>
				<th className='itemTd'>職位</th>
				<th className='itemTd'>性別</th>
				<th className='itemTd'>操作</th>
			</thead>
		    <tbody>{items}</tbody>
		  </table>
		);
	}
}

        現在拿看出上面的程式碼通過一個迴圈使用上了他的小藍Item.js,也就是我摘的這一段,react中有一個厲害的東西就是props大家一定要區分他和state的使用,在這裡就是通過props將ItemPanel從App中獲得的引數引數傳給個了Item,是不是稍微有點點繞,我的理解就是state就是用來表示狀態的,一般專案中都會對它置頂處理,也就是放到類似於爺爺輩,中間資料、函式的傳輸全部都使用props

 if(this.props.items && this.props.items.length!=0){
    this.props.items.forEach((item,index) => {
       items.push(<Item item={item} index={index} key={item.key} removeItem={this.props.removeItem}/>);
    });
 }else{
    items.push(<tr><th colSpan="5" className="tempEmpty">暫無使用者</th></tr>);
}

繫結資料的小藍Item登場

        接下來終於輪到我們的小藍登場了,因為已經是最底層的了所以就沒有引入除了react之外的其他東西,就是一個單一的模板了,用過layui的朋友對此一定不陌生,小藍的作用就類似於layui的template也就是模板的繫結,主要用於對資料的一個繫結,當然他繫結的資料也是通過props從爺爺輩App.js哪裡獲得的,至於App.js的資料獲取方法就比較多樣了,可以直接寫靜態資料給他,也可以通過引入'該頁面的js'(這裡的不太明白的話可以往下繼續看下)來獲得資料。

import React from 'react';
export default class Item extends React.Component{
	handlerDel(){
		this.props.removeItem(this.props.item.key);
	}
	
	render(){
		return (
			  <tr style={{'cursor': 'pointer'}}>
				<td className='itemTd'>{this.props.item.info.name}</td>
				<td className='itemTd'>{this.props.item.info.age}</td>
				<td className='itemTd'>{this.props.item.info.status}</td>
				<td className='itemTd'>{this.props.item.info.sex}</td>
				<td className='itemTd'>
				    <a className="itemBtn" onClick={this.handlerDel.bind(this)}>刪除</a>
				</td>
			  </tr>
		);
	}
}

放置頁面邏輯方法以及資料來源的js還有3″到達        

        是不是有點奇怪,怎麼從頭到尾都特麼沒見到我們的資料,被我吃了呀,別急麼,這不就出來了麼,duang duang duang 大家請看下面的程式碼,沒錯它就是一個模擬的資料來源以及邏輯程式碼的編寫的js。  

class Item{
    constructor(item) {
        this.info={};
        this.info.name=item.name;
        this.info.age=item.age;
        this.info.status=item.status;
        this.info.sex=item.sex;
        ++Item.key;
        this.key = Item.key;
    }

}
Item.key=0;
export default class Store {
    constructor() {
        this.allStore = [];
        if(Store.rawData && Store.rawData.length!=0){
            Store.rawData.forEach(
                item=>{
                    this.allStore.push(new Item(item));
                }
            )
        }
        this.store=this.allStore;
    }
    removeItem(key){
        let newStore=this.store.filter(item=>{
            return item.key!=key;
        })
        this.store=newStore;
        return this;
    }
}

Store.rawData= [{ sex: '男', age: 18, name: '曹操', status: '主公'},
    { sex: '女', age: 19, name: '郭嘉', status: '謀士'},
    { sex: '女', age: 23, name: '張遼', status: '將軍'},
    { sex: '女', age: 18, name: '張頜', status: '將軍'},
    { sex: '男', age: 22, name: '荀彧', status: '謀士'},
    { sex: '男', age: 41, name: '司馬懿', status: '謀士'},
    { sex: '男', age: 12, name: '典韋', status: '將軍'},
    { sex: '男', age: 33, name: '夏侯惇', status: '將軍'},
    { sex: '男', age: 50, name: '夏侯淵', status: '將軍'},
    { sex: '男', age: 12, name: '鄧艾', status: '將軍'},
    { sex: '男', age: 22, name: '于禁', status: '將軍'}]

        這裡我對著段js做一個詳細的講解,按我的理解大家都要把這麼個js之所以獨立出來,就是為了方便程式碼的管理,他就有點像之前使用js+html中的js,資料來源只是因為沒有後端程式碼模擬的一個東西,大家可以理解為通過ajax從後臺獲取的,這個js主要承擔的爺爺也就是App.js的大部分動態操作

        下面就是對這個可惡的js的分段介紹

        下面這段程式碼就是建立了一個Item的model,constructor就是初始化,他的思路和java中基本一樣,相當於以後會new一個有引數的物件,物件的引數也是一個物件(map),就是為了方便後續對資料的增刪改查,如果只是資料展示,完全沒有必要這樣你搞,直接用最底下的rawData也是一樣的。

class Item{
    constructor(item) {
        this.info={};
        this.info.name=item.name;
        this.info.age=item.age;
        this.info.status=item.status;
        this.info.sex=item.sex;
        ++Item.key;
        this.key = Item.key;
    }

}

        畢竟丟擲的不是Item,接下來這段程式碼呢,主要就是為了初始化一下丟擲去的Store,也是使用一個迴圈把它付給了屬性store,這樣在後續的var store=new Store之後,就可以使用建立的物件進行繫結,因為store.store就等同於需要使用的資料來源嘍,然後就可以通過props傳遞他讓他可以在最底層綁定出來了

constructor() {
        this.allStore = [];
        if(Store.rawData && Store.rawData.length!=0){
            Store.rawData.forEach(
                item=>{
                    this.allStore.push(new Item(item));
                }
            )
        }
        this.store=this.allStore;
    }