这是我们的app效果图。

        我们拿到了成品图,我们就需要去拆分成组件,首先第一个图片,我们拆分成三个组件,搜索框组件,列表展示组件,购物车组件,然后列表展示组件需要子组件作为列表的每一个元素。然后列表子组件的按钮都需要使用,所以也作为一个组件。这个按钮都可以使用,那么我们作为一个UI组件。购物车组件可以展开,展示购物车详情,这也是一个组件,然后套用列表组件,点击结算出现支付页面也是一个组件,包含的是购物清单,和支付按钮组件。

        大概的组件关系图我们画一下

                 可能有问题不过先开始写吧,写的时候发现问题去改。

   1.食物列表组件

        搜索和购物车都需要食物列表中展示的数据,所以先写这个组件。

        

        没什么好说的,一个Meals组件作为容器组件,Meal作为列表组件。遍历Meal展示。

                 首先根组件,我们要展示的数据,这里我们假设是服务器返回的数据,毕竟现在只是学习前端,然后我们去引入这个容器组件,把数据通过props传递过去,这样列表动态展示。

        

        然后Meals组件遍历传过来的数组,把里面的每一个对象作为参数传递给Meal列表组件,然后列表组件就可以去展示了。

                 

        这里我们直接props接到对象,然后展示。这样我们的食物列表组件就完成了。

2.食物列表子组件按钮组件 

        食物列表-》食物-》按钮组件,那么我们开始吧。首先我们看模板图这个按钮大家都在用,那就放UI文件里面。

        

        然后这个按钮

import React from 'react'
import classes from './Counter.module.css'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faPlus } from '@fortawesome/free-solid-svg-icons'
import { faMinus } from '@fortawesome/free-solid-svg-icons'
export default function Counter(props) {
    return (
        <div className={classes.Counter}>
            {
                (props.amount && props.amount !== 0) ? <>
                    <button className={classes.Sub}><FontAwesomeIcon icon={faMinus} /></button>
                    <span className={classes.count}>{props.amount}</span>
                </> : ''
            }
            <button className={classes.Add}><FontAwesomeIcon icon={faPlus} /></button>
        </div>
    )
}

         我们通过amount去判断是否展示我们的-号以及数字内容,有的话展示没有就不展示。注意我们现在的amount在我们食物组件传递的时候是没有这个值的,是undefined。

        

        这里我们用文字去输入-和+很难去居中,那么我们就需要去引入一些图标,去更好的实现我们的样式需求。那么我们添加小图标就需要去外面引入一些库。

引入 FontAwesome
1.引入依赖
npm i --save @fortawesome/fontawesome-svg-core
npm i --save @fortawesome/free-solid-svg-icons
npm i --save @fortawesome/free-regular-svg-icons
npm i --save @fortawesome/react-fontawesome@latest
npm install @fortawesome/fontawesome-svg-core @fortawesome/free-solid-svg-icons @fortawesome/free-regular-svg-icons @fortawesomereact-fontawesome@latest 
安装完依赖
引入组件
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
引入图标 icon属性
import { faPlus } from '@fortawesome/free-solid-svg-icons'
使用图标
<FontAwesomeIcon icon={faPlus} />

         可以去官方fortawesome查看怎么引入,这里我们引入的免费icons,然后使用就是react通过组件去引入,然后通过属性去选择你要的图片,官方文档里面都可以搜索到,没什么好说的,只是知道流程就可以了。看官方文档跟着走。

3.按钮事件生成购物车动态展示需要的数据

        

        画图,一定要坚持画思路。首先我们希望点击之后,购物车发生变化,

        而且还有购物详情列表。那我们购物车就很明显需要一个state作为数据来源展示,首先总数number类型,总价格number类型,还需要所有被选中汉堡的数据类型数组对象,包括amount,而且按钮本身也需要amount去改变自己的样式。一步步来

        先定义我们购物车想要展示就需要用到的数据。

 const [car, setCar] = React.useState({
        item: [],
        totalAmount: 0,
        totalPrice: 0
    })

            那么这里面所有的初始值都为空,我们就需要在点击事件发生的一瞬间给它加上点击事件发生时的meal,以及设置一个amount,以及price和amount累加。

   const addCar = (meal) => {
        console.log(meal);

        //首先浅复制car 不然直接更新会覆盖丢失其他的
        const newCar = { ...car }
        //通过find发放去判断我现在添加的meal是不是已经有了,没有就添加然后amount设置为1有了就不用只需要amount++就ok了
        const isHave = newCar.items.find((item) => { return (item.id === meal.id) })
        if (!isHave) {
            newCar.items.push(meal)
            meal.amount = 1
        } else {
            meal.amount += 1
        }
        //总数加1
        newCar.totalAmount += 1
        //总价格加当前添加meal的价格
        newCar.totalPrice += meal.price
        //然后更新
        setCar(newCar)
    }

        这就是完整的点击事件的js逻辑,点我们点击事件发生的时候,传当前发生的列表数据通过函数参数的形式,然后我们先浅赋值我们想要更新的对象,然后用find找到我们当前添加的列表id是不是已经有了,没有就添加进去meal,有的话只是数量加1,然后总数加1,总价格加当前列表的price。还是很简单的逻辑。

 //减少商品的数量
    const delCar = (meal) => {
        const newCar = { ...car }
        meal.amount -= 1
        let newItems
        if (meal.amount === 0) {
            newItems = newCar.items.filter((item) => { return (item.id !== meal.id) })
        } else {
            newItems = [...newCar.items]
        }
        newCar.totalAmount -= 1
        newCar.totalPrice -= meal.price
        const newCar1 = {
            ...newCar,
            items: newItems
        }
        setCar(newCar1)
    }

        那么减少按钮的逻辑呢,首先我们浅复制,然后点击事件发生就数量-1,然后我们去筛选出点击事件发生的列表,如果是0就踢出去,如果不是0,就原来的Items保留,只不过我们修改了items这个对象中的一个属性,所以我们需要覆盖掉之前的,而且totalAmount-=1以及totalPrice需要更改后保留,我们新定义一个对象,复制newCar,然后把newItems覆盖进去,然后更新car就完成了整个购物车的数据改变了。接下来展示就可以了。

        但是有一个问题是,我们通过props传递函数,通过调用函数传参数的方式,实现子组件向父组件传递一些数据,这显然很麻烦,如果套了10层就需要一直传下去,不过这个就在下个博客解决吧。这里主要是项目实现了动态展示数据。以及添加删除的简单js逻辑。

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐