React入门实战美食清单

Posted 安之ccy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了React入门实战美食清单相关的知识,希望对你有一定的参考价值。

今天要实现的功能是一个简易的美食清单,效果是这样的:

在这里插入图片描述


功能描述:

  1. 展示美食菜品的价格、图片、描述
  2. 点击分类按钮,展示该类别的菜品

涉及的组件:

组件备注
Menu展示菜品及信息
Categories菜品分类标签

菜品数据:

字段备注
id菜品标识
title菜品名称
category菜品分类
price菜品价格
img菜品图片
desc菜品描述

思路整理

  1. 创建一个所有菜品的展示页面,即Menu组件,将准备好的菜品数据传入
  2. 定义一个按标签过滤的过滤函数(使用filter),传递给Categories组件,由改组件调用过滤函数
  3. 定义一个存放菜品标签(去重后)的state,传入Categories组件,在该组件中动态生成菜品种类的按钮
  4. 点击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;

其中,值得一提的是“标签切换”功能的实现

  1. 我定义了一个数组flag,用于标识四个标签中被点击的那个标签。
  2. 由于同一时间段只能有一个标签被点击,另一个被点击时,前一个被点击的样式就需要取消掉,因此,当监听到某个标签被点击时,我直接把flag清空,并把当前标签的index值置为true (1)
  3. 另外,在鼠标悬停在标签上方时,也增加了相应的样式,看起来效果更舒服些

相关的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入门实战美食清单的主要内容,如果未能解决你的问题,请参考以下文章

React入门实战页面跳转(附完整代码)

React入门实战页面跳转(附完整代码)

React入门实战联系人列表Contact(附完整代码)

React入门实战联系人列表Contact(附完整代码)

HTML5期末大作业:餐饮美食网站设计——咖啡(10页) HTML+CSS+JavaScript 学生DW网页设计作业成品 web课程设计网页规划与设计 咖啡网页设计 美食餐饮网页设计...(代码片段

Redux+React-Redux 最新入门实战指南?