React系列三 – 阶段案例练习
2010 年 6 月 25 日
一. 书籍购物车说明
1.1. 案例介绍
现在我们来做一个相对综合一点的练习:书籍购物车;
案例效果如下:
案例说明:
-
1.在界面上以表格的形式,显示一些书籍的数据;
-
2.在底部显示书籍的总价格;
-
3.点击+或者-可以增加或减少书籍数量(如果为1,那么不能继续-);
-
4.点击移除按钮,可以将书籍移除(当所有的书籍移除完毕时,显示:购物车为空~);
1.2. 项目的搭建
这里,我们使用React将默认的数据先展示出来:
Document table { border: 1px solid #e9e9e9; border-collapse: collapse; } td, th { border: 1px solid #e9e9e9; padding: 8px 16px; } th { background-color: #f7f7f7; color: #5c6b77; } .counter { margin: 0 5px; } class App extends React.Component { constructor(props) { super(props); this.state = { books: [ { id: 1, name: '《算法导论》', date: '2006-9', price: 85.00, count: 1 }, { id: 2, name: '《UNIX编程艺术》', date: '2006-2', price: 59.00, count: 1 }, { id: 3, name: '《编程珠玑》', date: '2008-10', price: 39.00, count: 1 }, { id: 4, name: '《代码大全》', date: '2006-3', price: 128.00, count: 1 }, ] } } render() { const { books } = this.state; return () } } ReactDOM.render(, document.getElementById("app"));
{ books.map((item, index) => { return ( 书籍名称 出版日期 价格 购买数量 操作 ) }) } {index + 1} {item.name} {item.date} {"¥" + item.price} {item.count}
二. 书籍购物车功能
1.1. 价格的显示
我们可以封装一个工具函数,用于格式化价格:
function formatPrice(price) { if (typeof price !== "number") { price = Number(price) || 0; } return "¥" + price.toFixed(2); }
对之前显示的价格进行格式化:
{formatPrice(item.price)}
封装一个App中的方法,用于获取商品总价格显示的内容:
getTotalPrice() { let totalPrice = 0; for (let book of this.state.books) { totalPrice += book.count * book.price } return "总价格:" + formatPrice(totalPrice); }
使用一个h2元素显示总价格:
{this.getTotalPrice()}
1.2. 数量的变化
封装一个方法,用于改变书籍的数量:
-
注意:在React中,要保证数据的不可变性;
-
所以,我们是先复制一份books,对其进行修改,再通过setState更新到最新的状态;
changeItem(index, counter) { const books = [...this.state.books]; this.setState({ books: books.map((item, indey) => { if (indey == index) { item.count += counter; } return item; }) }) }
修改jsx对应位置的代码:
<button disabled={item.count this.changeItem(index, -1)}>- {item.count}
1.3. 移除的操作
封装一个方法,用于移除对应的书籍:
removeItem(index) { const books = [...this.state.books]; this.setState({ books: books.filter((item, indey) => index !== indey) }) }
修改对应的移除jsx代码:
如果所有的书籍移除完毕,那么要显示购物车为空:
-
封装两个方法,一个用于获取显示购物车的jsx代码(后期会封装成一个组件),一个用于获取显示购物车为空的jsx代码(后期也可以封装为一个组件)
renderBooks() { const { books } = this.state; return () } renderEmpty() { return
{ books.map((item, index) => { return ( 书籍名称 出版日期 价格 购买数量 操作 ) }) } {index + 1} {item.name} {item.date} {formatPrice(item.price)} {item.count} {this.getTotalPrice()}
购物车为空~
}
重新编写render方法代码:
render() { const { books } = this.state; return books.length ? this.renderBooks() : this.renderEmpty(); }