通过计数器,tabbar与购物车等小案例来掌握之前学习过的条件渲染,列表渲染与属性绑定等知识
计数器
通过两个按钮来控制数字的增减,这个案例比较简单,直接将counter
作为响应式数据,并且点击按钮时进行修改就行
<body>
<div id="root"></div>
<script src="./lib/react.js"></script>
<script src="./lib/react-dom.js"></script>
<script src="./lib/babel.js"></script>
<script type="text/babel">
class App extends React.Component {
constructor() {
super()
this.state = {
counter: 0,
}
}
increament() {
this.setState({
counter: this.state.counter + 1,
})
}
decreament() {
this.setState({
counter: this.state.counter - 1,
})
}
render() {
return (
<div>
<button onClick={() => this.decreament()}>-</button>
<span style={{ padding: "10px" }}>{this.state.counter}</span>
<button onClick={() => this.increament()}>+</button>
</div>
)
}
}
const root = ReactDOM.createRoot(document.getElementById("root"))
root.render(<App />)
</script>
</body>
tabbar
功能为点击时切换选中状态,也就是修改背景色,通过该案例掌握事件绑定(传参)与属性绑定
<body>
<div id="root"></div>
<script src="./lib/react.js"></script>
<script src="./lib/react-dom.js"></script>
<script src="./lib/babel.js"></script>
<script type="text/babel">
class App extends React.Component {
constructor() {
super()
this.state = {
idx: 0,
tabs: ["首页", "分类", "相册", "关于"],
}
}
getIdx(idx) {
this.setState({
idx,
})
}
render() {
return (
<div style={{ display: "flex" }}>
{this.state.tabs.map((item, idx) => {
return (
<div
onClick={() => this.getIdx(idx)}
style={{
padding: "10px",
backgroundColor: idx === this.state.idx ? "#368" : "#ccc",
}}
key={item}
>
{item}
</div>
)
})}
</div>
)
}
}
const root = ReactDOM.createRoot(document.getElementById("root"))
root.render(<App />)
</script>
</body>
- 通过比较state中的idx与当前元素的idx是否相等判断是否为激活状态(style中的背景色)
- 为了修改idx,在绑定事件时传入当前元素的idx从而确认点击的tab
购物车
这个案例实现了以下功能
- 对于books进行列表渲染
- 按钮控制当前 book的
count
- 数量为0时,减按钮处于禁用状态
- 下方可显示总价格
- 点击删除按钮可以删除当前整条数据
<body>
<div id="root"></div>
<script src="./lib/react.js"></script>
<script src="./lib/react-dom.js"></script>
<script src="./lib/babel.js"></script>
<script type="text/babel">
const books = [
{ name: "《你不知道的JavaScript》", prace: 100, count: 0, id: 1 },
{ name: "《Javascript高级程序设计》", prace: 87, count: 0, id: 2 },
{ name: "《图解HTTP》", prace: 78, count: 0, id: 3 },
{ name: "《算法的乐趣》", prace: 56, count: 0, id: 4 },
]
class App extends React.Component {
constructor() {
super()
this.state = {
books,
}
}
increament(idx) {
const newBooks = [...this.state.books]
newBooks[idx].count += 1
this.setState({
books: newBooks,
})
}
decreament(idx) {
const newBooks = [...this.state.books]
newBooks[idx].count -= 1
this.setState({
books: newBooks,
})
}
removeItem(idx) {
const newBooks = [...this.state.books]
newBooks.splice(idx, 1)
this.setState({
books: newBooks,
})
}
render() {
return (
<div>
<table>
<thead>
<tr>
<td>序号</td>
<td>书名</td>
<td>单价</td>
<td>数量</td>
<td>移除</td>
</tr>
</thead>
{this.state.books.length === 0 && <h1>购物车为空</h1>}
<tbody>
</table>
<div style={{ fontSize: "22px" }}>
总价格
{"¥" +
this.state.books.reduce((preValue, item) => {
console.log(preValue, item.count, item.prace)
return preValue + item.count * item.prace
}, 0)}
</div>
</div>
)
}
}
const root = ReactDOM.createRoot(document.getElementById("root"))
root.render(<App />)
</script>
</body>
div {
display: flex;
flex-direction: column;
justify-content: center;
flex-wrap: wrap;
text-align: center;
}
table {
border: 1px solid #ccc;
}
thead {
background-color: #ccc;
}
td {
padding: 10px;
}
span {
padding: 0px 10px;
}
- 列表渲染通过
map
实现- 增减按钮,通过传入当前item的idx来正确修改count
- 禁用按钮通过判断
item
的count是否为0- 总价通过
reduce
方法来遍历books
- 删除按钮通过传入当前删除item的idx,然后通过数组的splice方法移除