React結合es6例項教程
前言
本文主要是關於webpack+es6+react的基礎頁面例項的講解,通過這個簡單的單頁面的講解,當掌握單頁面的用法後,實現具體專案是也就是通過控制檯呼叫不同的頁面,本文為基礎帖到實戰帖的過度,適合有react基礎的小夥伴,大神請繞行哦。
ok我們廢話不多講直接上圖,先給大家看下完成後的效果圖,是不是很醜,沒關係啦!懂得原理剩下的交給css去做啦,什麼配色呀,圖片新增呀,大多都是ui的事情,你都懂了不就是搶了別人飯碗了嗎,不過吧有一個好的頁面鑑賞和規劃能力也是必不可少的,但是大家都是菜鳥就不拘小節一下下啦,忍住往下看。
頁面整體
使用react製作頁面時,我覺得吧應該從對頁面劃分開始
圖中可以看出頁面是由三層巢狀關係也就是程式碼中的巢狀,綠色的是爺爺輩,紅色自然就是兒子啦,小藍就是孫子啦,我們發現爺爺有三個兒子,分別是header、ItemPanel、Footer,只有ItemPanel到了結婚年紀了生下了小藍Item,因此js之間的關係也就非常明瞭了,然後我們去看下面的實現過程。
頁面容器App.js
在爺爺輩的App.js中通過import引入自己的三個兒子,注意import不是react特有的方法
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;
}