這個是我react的入門項目, 因爲使用了bootstrap模板, 若使用create-react-app 或者webpack等構建服務器項目就比較複雜, 所以本項目只使用了最簡單的 在HTML頁面引入react 的方式 構建項目.
教程使用的模板頁面如下:
項目已傳到git上,上鍊接~
第一步:
引入react. (爲了避免忘記, 我在head中引入)
<!-- react -->
<script src="../build/react.development.js"></script>
<script src="../build/react-dom.development.js"></script>
<script src="../build/babel.min.js"></script>
第二步:
將應該作爲組件的部分劃分出來. 本頁面需要摳出2個組件, 一是GoodList, 二是GoodItem. GoodList用來接收服務器傳回的菜品數組. GoodItem 用來顯示單個菜品. 這一步是思考, 先不用刪改代碼. 需注意: 組件的html必須只有一個根元素, 所有組件的首字母要大寫, 爲的是和其他HTML元素區分開 !
GoodList: ( 該組件是一個table. 這裏有使用GoodItem組件, 其他的我們下面再講 )
<table id="demo-foo-addrow" className="table m-t-30 table-hover contact-list"
data-page-size="10">
<thead>
<tr>
<th>當前:菜單</th>
</tr>
</thead>
<tbody>
{
this.state.goods.map(item =>
<GoodItem
good = {item}
key = {item.id}
/>
)
}
</tbody>
<tfoot>
<tr>
<div id="add-contact" className="modal fade in" tabIndex="-1" role="dialog"
aria-labelledby="myModalLabel" aria-hidden="true">
<div className="modal-dialog">
<div className="modal-content">
<div className="modal-header">
<h4 className="modal-title" id="myModalLabel">確定加入?</h4>
<button type="button" className="close" data-dismiss="modal" aria-hidden="true">×</button>
</div>
<div className="modal-footer">
<button type="button" className="btn btn-info waves-effect" data-dismiss="modal">確認</button>
<button type="button" className="btn btn-default waves-effect" data-dismiss="modal">取消</button>
</div>
</div>
</div>
</div>
<td colspan="5">
<div className="text-right" style={{marginRight: '50%'}}>
<ul className="pagination"> </ul>
</div>
</td>
</tr>
</tfoot>
</table>
GoodItem:
<tr>
<td style={{width:'220px'}}>
<img src="img/01.jpg" alt="" style={{width:'200px', height: '100px'}}/>
</td>
<td>
<ul>
<li>菜品:{item.goodname}</li>
<li>價格:{item.price}</li>
<li>數量:
<select>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
</select>
<button type="button" className="btn btn-info btn-rounded"
data-toggle="modal"
data-target="#add-contact">加入購物車</button>
</li>
</ul>
</td>
</tr>
第三步:
在<body>的最末尾,加入script標籤,在標籤中寫react組件。如下:
<!-- react組件 -->
<script type="text/babel">
//組件在這裏寫~~~
</script>
組件分爲有狀態組件和無狀態組件. 上面的GoodList就是有狀態組件, 因爲它需要接收動態的goods數據, 而上面的GoodItem 就是無狀態組件. 因爲它只需要進行數據展示. 它所需要的數據只要GoodList傳給它就好.
有狀態組件如何寫 ? GoodList :
我們從上到下講解各個函數.
constructor函數是初始化函數, 需要調用super(props), 用來完成組件的初始化工作。下面的this.state 定義了組件的狀態。也就是組件需要用到的數據。此處我是寫死的,其實應該在後面的componentDidMount(組件掛載完畢)函數中請求服務器後使用this.setState函數設置。
本頁面因爲服務器沒有開啓,故componentDidMount函數中的ajax請求先註釋掉。
render方法return的是代表組件UI的React元素。也就是第二步中我們劃分出來的那兩個HTML元素。這裏要注意,react使用了JSX語法,onclick要改成onClick(其他事件類似),class要改成className。
組件外:
ReactDOM.render()方法,是將該組件掛載到html頁面上的id爲goodList的元素上。這裏在摳出GoodList組件之後,在HTML頁面的原位置加一個div,id爲goodList。
class GoodList extends React.Component {
constructor(props) {
super(props)
this.state = {
goods: [
{
id: 1,
goodname: '以前好吃的鍋仔面',
price: '10',
num: 999,
imageUrl: 'img/01.jpg'
},
{
id: 2,
goodname: '以前好吃的鍋仔面',
price: '10',
num: 999,
imageUrl: 'img/01.jpg'
},
{
id: 3,
goodname: '以前好吃的鍋仔面',
price: '10',
num: 999,
imageUrl: 'img/01.jpg'
},
{
id: 4,
goodname: '以前好吃的鍋仔面',
price: '10',
num: 999,
imageUrl: 'img/01.jpg'
},
]
}
}
componentDidMount() {
// 獲取商品列表
// $.ajax({
// type: 'POST',
// url: global.targetUrl,
// data: {
// ''
// },
// success: function (res) {
// console.log('返回的',res)
// if (res.resultMsg.code === 1000) {
// location.href = "menu.html";
// }
// }
// })
}
render() {
return (
<table id="demo-foo-addrow" className="table m-t-30 table-hover contact-list"
data-page-size="10">
<thead>
<tr>
<th>當前:菜單</th>
</tr>
</thead>
<tbody>
{
this.state.goods.map(item =>
<GoodItem
good = {item}
key = {item.id}
/>
)
}
</tbody>
<tfoot>
<tr>
<div id="add-contact" className="modal fade in" tabIndex="-1" role="dialog"
aria-labelledby="myModalLabel" aria-hidden="true">
<div className="modal-dialog">
<div className="modal-content">
<div className="modal-header">
<h4 className="modal-title" id="myModalLabel">確定加入?</h4>
<button type="button" className="close" data-dismiss="modal" aria-hidden="true">×</button>
</div>
<div className="modal-footer">
<button type="button" className="btn btn-info waves-effect" data-dismiss="modal">確認</button>
<button type="button" className="btn btn-default waves-effect" data-dismiss="modal">取消</button>
</div>
</div>
</div>
</div>
<td colspan="5">
<div className="text-right" style={{marginRight: '50%'}}>
<ul className="pagination"> </ul>
</div>
</td>
</tr>
</tfoot>
</table>
)
}
}
ReactDOM.render (
<GoodList />,
document.getElementById('goodList')
)
無狀態組件如何寫?GoodItem:
這個照比有狀態組件就簡單很多了。在上面GoodList組件中使用了GoodItem組件。如下:
因爲使用了js語法(map),所以需要用大括號將其包裹進去,表示它是一個js代碼塊。後面的item和item.id被花括號包起也是這樣滴原因~
其中直接像使用HTML元素一樣使用了GoodItem組件。並向其傳入了good和key。item是循環GoodList組件中的this.state.goods數組的每一個good數組元素。key是React使用Diff算法修改虛擬DOM時需要用其作爲判斷的(你不用也得給)。
傳入的good怎麼獲取? 無狀態組件有個參數叫props,在下面代碼第一行,const item = props.good 這樣就把good賦值給了item。就可以在下文中使用了!使用的時候還是要注意,需要用花括號包起。
還有內聯樣式方面:使用了兩個大括號,因爲第一個表示它是一個JavaScript表達式,第二個表示這個表達式是一個對象。(儘量不要使用內聯樣式。比如220px還需要用 ' ' 包裹)
所有單標籤元素,比如img,input,都需要在最後加入 / 反斜槓。我們的模板沒有,所以需要修改
這個組件在GoodList組件中使用,不需要再手動掛載到HTML中,所以不需要ReactDOM.render。
function GoodItem (props) {
const item = props.good
console.log (item)
return (
<tr>
<td style={{width:'220px'}}>
<img src="img/01.jpg" alt="" style={{width:'200px', height: '100px'}}/>
</td>
<td>
<ul>
<li>菜品:{item.goodname}</li>
<li>價格:{item.price}</li>
<li>數量:
<select>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
</select>
<button type="button" className="btn btn-info btn-rounded"
data-toggle="modal"
data-target="#add-contact">加入購物車</button>
</li>
</ul>
</td>
</tr>
)
}