React入门实战美食清单
Posted 安之ccy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了React入门实战美食清单相关的知识,希望对你有一定的参考价值。
今天要实现的功能是一个简易的美食清单,效果是这样的:
功能描述:
- 展示美食菜品的价格、图片、描述
- 点击分类按钮,展示该类别的菜品
涉及的组件:
组件 | 备注 |
---|---|
Menu | 展示菜品及信息 |
Categories | 菜品分类标签 |
菜品数据:
字段 | 备注 |
---|---|
id | 菜品标识 |
title | 菜品名称 |
category | 菜品分类 |
price | 菜品价格 |
img | 菜品图片 |
desc | 菜品描述 |
思路整理
- 创建一个所有菜品的展示页面,即Menu组件,将准备好的菜品数据传入
- 定义一个按标签过滤的过滤函数(使用filter),传递给Categories组件,由改组件调用过滤函数
- 定义一个存放菜品标签(去重后)的state,传入Categories组件,在该组件中动态生成菜品种类的按钮
- 点击Categories组件中的菜品按钮,筛选出该类别的菜品并展示
代码:
第一步:先准备一下数据,考虑到篇幅,此处仅列举一个
const menu = [
{
id:1,
title:'小龙虾',
category:"夜宵",
price:"¥50",
img:"./imgs/1.jpg",
desc:"Wish you a good mood every day, eat well and drink well"
}
]
export default menu;
第二步:做一个简单的页面,展示所有的菜品
import React from 'react'
// Menu.js
const Menu = ({ menuItems }) => {
return (
// 显示菜品及信息
<div className='section-center'>
{menuItems.map((item) => {
const { id, img, price, title, desc } = item;
return (
<article className='menu-item' key={id}>
<img src={img} alt={title} className='photo' />
<div className='item-info'>
<header>
<h4>{title}</h4>
<h4>{price}</h4>
</header>
<p className="item-text">{desc}</p>
</div>
</article>
)
})}
</div>
)
}
export default Menu;
在主组件中引入这个展示菜品的组件Menu.js
import React, { useState } from 'react'
import items from './data' // 准备的数据
import Menu from './components/Menu'
function App() {
// 初始化菜品列表,传入菜品数据
const [menuItems, setMenuitems] = useState(items);
return (
<main>
<section className='menu section'>
<div className='title'>
<h2>美食菜单</h2>
<div className='underline'></div>
</div>
<Menu menuItems={menuItems} />
</section>
</main>
);
}
export default App;
第三步:添加可点击的标签按钮,点击某个标签就展示某种菜品
定义好实现该功能的函数filterCategories
// App.js
// 获取所有菜品的标签并去重,加入"所有"选项,代表所有菜品
const allCategories = ["所有", ...new Set(items.map(item => item.category))];
console.log(allCategories); // ["all", "夜宵", "饮品", "甜品"]
// 过滤函数,当点击某一标签按钮时,只展示该种类菜品
const filterCategories = (category) => {
if (category === '所有') {
setMenuitems(items);
}
else {
let newItem = items.filter(item => item.category === category);
setMenuitems(newItem)
console.log('menuItems', menuItems)
}
}
// 在页面中使用分类标签组件,实现点击某标签就展示该种类菜品的功能
return (
<main>
<section className='menu section'>
<div className='title'>
<h2>美食菜单</h2>
<div className='underline'></div>
</div>
<Categories filterCategories={filterCategories} categories={categories} />
<Menu menuItems={menuItems} />
</section>
</main>
);
在Categories组件中调用
import React,{useState} from 'react'
const Categories = ({ filterCategories, categories }) => {
// 初始化state,用于标记某标签是否被点击
const [flag, setFlag] = useState([0,0,0,0])
return (
<section className='btn-container'>
{categories.map((ctg, i) => {
console.log(ctg,i)
// 绑定点击事件,当点击该标签时,调用过滤函数,将该标签的标签值传递给过滤函数
return (
<button className={`filter-btn ${flag[i]? 'active': null}`} key={i}
onClick={(e) => {
filterCategories(ctg);
// 当前标签被点击,其他标签取消点击
let newFlag = [0,0,0,0];
newFlag[i] = 1;
setFlag(newFlag);
}} >
{ctg}
</button>
)
})}
</section>
)
}
export default Categories;
其中,值得一提的是“标签切换”功能的实现
- 我定义了一个数组flag,用于标识四个标签中被点击的那个标签。
- 由于同一时间段只能有一个标签被点击,另一个被点击时,前一个被点击的样式就需要取消掉,因此,当监听到某个标签被点击时,我直接把flag清空,并把当前标签的index值置为true (1)
- 另外,在鼠标悬停在标签上方时,也增加了相应的样式,看起来效果更舒服些
相关的css样式(主要使用flex布局):
main {
max-width: 1300px;
margin: 10px auto;
}
.title {
font-size: 25px;
text-align: center;
}
.underline {
border:1px solid orange;
width:200px;
margin: -20px auto 15px auto;
}
.btn-container {
margin: 10px auto;
text-align: center;
}
.btn-container button {
margin: 5px 10px;
width: auto;
height: 50px;
padding: 5px 10px;
color: orange;
font-size: 24px;
border: none;
background-color: transparent;
border-radius: 8px;
}
.btn-container button:hover, .btn-container .active {
background-color: #c59d5f;
color: white;
}
.section-center {
display: flex;
flex-wrap: wrap;
justify-content:space-between
}
.menu-item {
display: flex;
width: 600px;
margin: 10px;
border: 2px solid orange;
border-radius: 3px;
padding: 5px;
}
.menu-item .photo {
width:400px;
margin: 10px;
}
.menu-item .item-info {
display: flex;
width: 200px;
flex-direction: column;
font-size: 20px;
}
.item-info header {
display: flex;
justify-content:space-between;
border-bottom: 1px solid gray;
}
完成~
以上是关于React入门实战美食清单的主要内容,如果未能解决你的问题,请参考以下文章
HTML5期末大作业:餐饮美食网站设计——咖啡(10页) HTML+CSS+JavaScript 学生DW网页设计作业成品 web课程设计网页规划与设计 咖啡网页设计 美食餐饮网页设计...(代码片段