import { useNavigate } from "react-router-dom"
import React from 'react'
import { SideBar, Image, List, Popup, Badge } from 'antd-mobile'
import { useState } from 'react'
import "./Goods.css"
export default function Goods() {
const navigate = useNavigate()
const [activeKey, setActiveKey] = useState('key1')
const [cartList, setCartList] = useState([])
const [visible1, setVisible1] = useState(false)
const tabs = [
{
key: 'key1',
title: '手工水饺',
},
{
key: 'key2',
title: '小咸菜',
badge: '5',
},
{
key: 'key3',
title: '汤汤水水',
badge: '99+',
},
]
const [users, setUsers] = useState([
{
id: 1,
avatar:
'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fsafe-img.xhscdn.com%2Fbw1%2F1194c0a2-6286-45ae-9e22-69d8190083f6%3FimageView2%2F2%2Fw%2F1080%2Fformat%2Fjpg&refer=http%3A%2F%2Fsafe-img.xhscdn.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1683513502&t=261e904d3e43fdfef8cb640c3897da46',
name: '韭菜鸡蛋水饺',
description: '好吃不贵 月售44',
price: 18,
num: 0,
state: false,
isChecked: false,
},
{
id: 2,
avatar:
'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fsafe-img.xhscdn.com%2Fbw1%2F1194c0a2-6286-45ae-9e22-69d8190083f6%3FimageView2%2F2%2Fw%2F1080%2Fformat%2Fjpg&refer=http%3A%2F%2Fsafe-img.xhscdn.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1683513502&t=261e904d3e43fdfef8cb640c3897da46',
name: '猪肉韭菜水饺',
description: '好吃不贵 月售44',
price: 20,
num: 0,
state: false,
isChecked: false,
},
{
id: 3,
avatar:
'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fsafe-img.xhscdn.com%2Fbw1%2F1194c0a2-6286-45ae-9e22-69d8190083f6%3FimageView2%2F2%2Fw%2F1080%2Fformat%2Fjpg&refer=http%3A%2F%2Fsafe-img.xhscdn.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1683513502&t=261e904d3e43fdfef8cb640c3897da46',
name: '猪肉大葱水饺',
description: '好吃不贵 月售44',
price: 21,
num: 0,
state: false,
isChecked: false,
},
{
id: 4,
avatar:
'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fsafe-img.xhscdn.com%2Fbw1%2F1194c0a2-6286-45ae-9e22-69d8190083f6%3FimageView2%2F2%2Fw%2F1080%2Fformat%2Fjpg&refer=http%3A%2F%2Fsafe-img.xhscdn.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1683513502&t=261e904d3e43fdfef8cb640c3897da46',
name: '三鲜水饺',
description: '好吃不贵 月售44',
price: 30,
num: 0,
state: false,
isChecked: false,
},
{
id: 5,
avatar:
'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fsafe-img.xhscdn.com%2Fbw1%2F1194c0a2-6286-45ae-9e22-69d8190083f6%3FimageView2%2F2%2Fw%2F1080%2Fformat%2Fjpg&refer=http%3A%2F%2Fsafe-img.xhscdn.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1683513502&t=261e904d3e43fdfef8cb640c3897da46',
name: '腌黄瓜',
description: '好吃不贵 月售36',
price: 10,
num: 0,
state: false,
isChecked: false,
},
{
id: 6,
avatar:
'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fsafe-img.xhscdn.com%2Fbw1%2F1194c0a2-6286-45ae-9e22-69d8190083f6%3FimageView2%2F2%2Fw%2F1080%2Fformat%2Fjpg&refer=http%3A%2F%2Fsafe-img.xhscdn.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1683513502&t=261e904d3e43fdfef8cb640c3897da46',
name: '腌芹菜',
description: '好吃不贵 月售18',
price: 20,
num: 0,
state: false,
isChecked: false,
},
{
id: 7,
avatar:
'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fsafe-img.xhscdn.com%2Fbw1%2F1194c0a2-6286-45ae-9e22-69d8190083f6%3FimageView2%2F2%2Fw%2F1080%2Fformat%2Fjpg&refer=http%3A%2F%2Fsafe-img.xhscdn.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1683513502&t=261e904d3e43fdfef8cb640c3897da46',
name: '鸡蛋汤',
description: '好吃不贵 月售106',
price: 3,
num: 0,
state: false,
isChecked: false,
},
{
id: 8,
avatar:
'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fsafe-img.xhscdn.com%2Fbw1%2F1194c0a2-6286-45ae-9e22-69d8190083f6%3FimageView2%2F2%2Fw%2F1080%2Fformat%2Fjpg&refer=http%3A%2F%2Fsafe-img.xhscdn.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1683513502&t=261e904d3e43fdfef8cb640c3897da46',
name: '丸子汤',
description: '好吃不贵 月售56',
price: 5,
num: 0,
state: false,
isChecked: false,
}
])
const handleNum = (obj, str) => {
if (str === "jia") {
obj.num++
obj.state = true
let idx = users.findIndex(item => { return item.id === obj.id })
users[idx] = obj
setUsers([...users])
let idx2 = cartList.findIndex(item => { return item.id === obj.id })
if (idx2 !== -1) {
cartList[idx2] = obj
setCartList([...cartList])
}
if (idx2 === -1) {
cartList.push(obj)
setCartList([...cartList])
}
}
if (str === "jian") {
if (obj.num < 2) {
if (obj.num === 1) {
obj.num--
}
obj.state = false
let idx = users.findIndex(item => { return item.id === obj.id })
users[idx] = obj
setUsers([...users])
let idx2 = cartList.findIndex(item => { return item.id === obj.id })
cartList.splice(idx2, 1)
setCartList([...cartList])
return false
}
obj.num--
let idx = users.findIndex(item => { return item.id === obj.id })
users[idx] = obj
setUsers([...users])
let idx2 = cartList.findIndex(item => { return item.id === obj.id })
cartList[idx2] = obj
setCartList([...cartList])
}
}
const handleGoods = () => {
if (cartList.reduce((num, a) => { num += a.price * a.num; return num }, 0) !== 0) {
setVisible1(true)
}
}
const Getcollect = () => document.getElementById("cart")
// 创建小球添加动画
const createBall = (left, top) => {
// 创建div元素
let Ball = document.createElement('div')
// 给div定位
Ball.style.position = "absolute";
// div的left和span的left是一样的
Ball.style.left = left + 'px'
// div的top和span的top是一样的
Ball.style.top = top + 'px'
Ball.style.width = '20px'
Ball.style.height = '20px'
Ball.style.borderRadius = '50%'
Ball.style.backgroundColor = 'red'
// 贝塞尔曲线
Ball.style.transition = "left .6s linear, top .6s cubic-bezier(0.5, -0.5, 1, 1)";
// 向父元素最后添加
document.body.appendChild(Ball);
// 添加动画属性
setTimeout(() => {
Ball.style.left = Getcollect().offsetLeft + Getcollect().offsetWidth / 2 + "px";
Ball.style.top = 500 + "px";
}, 0);
//动画结束后,删除自己
// ontransitionend事件 是在 transition过度完之后执行的
Ball.ontransitionend = function () {
Ball.remove();
};
}
const add = (e, user) => {
handleNum(user, "jia")
// console.log(Getcollect().offsetTop)
// 获取当前span的x和y的值
let x = e.clientX
let y = e.clientY
// 调用函数把x和y当参数传过去
createBall(x, y)
}
return (
<div className='goods'>
<div className="container">
<div className="side">
<SideBar activeKey={activeKey} onChange={setActiveKey}>
{tabs.map(item => (
<SideBar.Item key={item.key} title={item.title} />
))}
</SideBar>
</div>
<div className="main">
<div
className="content"
style={{ display: activeKey === "key1" ? "flex" : "" }}
>
<List header='手工水饺'>
{users.filter(item => { return item.id <= 4 }).map(user => (
<List.Item
key={user.name}
prefix={
<Image
src={user.avatar}
style={{ borderRadius: 20 }}
fit='cover'
width={60}
height={60}
/>
}
description={user.description}
>
<div className='list-content'>
<h4 style={{ color: "black" }} onClick={() => { navigate("/detail", { state: user }) }}>{user.name}</h4>
<div style={{ display: "flex", justifyContent: "space-between" }}>
<span style={{ color: "red" }}>¥{user.price}</span>
<div style={{ display: "flex" }}>
{user.state ?
<div style={{ display: "flex" }}>
<span className={user.state ? "qiu-enter" : "qiu-exit"} onClick={() => { handleNum(user, "jian") }} style={{ boxSizing: "border-box", display: "block", width: "20px", height: "20px", background: "white", border: "1px solid orange", display: "flex", alignItems: "center", justifyContent: "center", color: "black", borderRadius: "5px" }}>-</span>
<div style={{ margin: "0px 5px", color: "black" }}>{user.num}</div>
</div>
:
<div style={{ display: "flex" }}>
<span className={user.state ? "qiu-enter" : "qiu-exit"} onClick={() => { handleNum(user, "jian") }} style={{ boxSizing: "border-box", display: "block", width: "20px", height: "20px", background: "white", border: "1px solid orange", display: "flex", alignItems: "center", justifyContent: "center", color: "black", borderRadius: "5px" }}>-</span>
</div>
}
<span onClick={(e) => { add(e, user) }} style={{ display: "block", width: "20px", height: "20px", background: "orange", display: "flex", alignItems: "center", justifyContent: "center", color: "black", borderRadius: "5px" }}>+</span>
<div id="red-qiu"></div>
</div>
</div>
</div>
</List.Item>
))}
</List>
</div>
<div
className="content"
style={{ display: activeKey === "key2" ? "flex" : "" }}
>
<List header='小咸菜'>
{users.filter(item => { return item.id <= 6 && item.id >= 5 }).map(user => (
<List.Item
key={user.name}
prefix={
<Image
src={user.avatar}
style={{ borderRadius: 20 }}
fit='cover'
width={60}
height={60}
/>
}
description={user.description}
>
<div className='list-content'>
<h4 style={{ color: "black" }} onClick={() => { navigate("/detail", { state: user }) }}>{user.name}</h4>
<div>
<h5 style={{ display: "flex", justifyContent: "space-between" }}>
<span style={{ color: "red" }}>¥{user.price}</span>
<div style={{ display: "flex" }}>
{user.state ?
<div style={{ display: "flex" }}>
<span onClick={() => { handleNum(user, "jian") }} style={{ boxSizing: "border-box", display: "block", width: "20px", height: "20px", background: "white", border: "1px solid orange", display: "flex", alignItems: "center", justifyContent: "center", color: "black", borderRadius: "5px" }}>-</span>
<div style={{ margin: "0px 5px", color: "black" }}>{user.num}</div>
</div>
: ""}
<span onClick={(e) => { add(e, user) }} style={{ display: "block", width: "20px", height: "20px", background: "orange", display: "flex", alignItems: "center", justifyContent: "center", color: "black", borderRadius: "5px" }}>+</span>
</div>
</h5>
</div>
</div>
</List.Item>
))}
</List>
</div>
<div
className="content"
style={{ display: activeKey === "key3" ? "flex" : "" }}
>
<List header='汤汤水水'>
{users.filter(item => { return item.id <= 8 && item.id >= 7 }).map(user => (
<List.Item
key={user.name}
prefix={
<Image
src={user.avatar}
style={{ borderRadius: 20 }}
fit='cover'
width={60}
height={60}
/>
}
description={user.description}
>
<div className='list-content'>
<h4 style={{ color: "black" }} onClick={() => { navigate("/detail", { state: user }) }}>{user.name}</h4>
<div>
<h5 style={{ display: "flex", justifyContent: "space-between" }}>
<span style={{ color: "red" }}>¥{user.price}</span>
<div style={{ display: "flex" }}>
{user.state ?
<div style={{ display: "flex" }}>
<span onClick={() => { handleNum(user, "jian") }} style={{ boxSizing: "border-box", display: "block", width: "20px", height: "20px", background: "white", border: "1px solid orange", display: "flex", alignItems: "center", justifyContent: "center", color: "black", borderRadius: "5px" }}>-</span>
<div style={{ margin: "0px 5px", color: "black" }}>{user.num}</div>
</div>
: ""}
<span onClick={(e) => { add(e, user) }} style={{ display: "block", width: "20px", height: "20px", background: "orange", display: "flex", alignItems: "center", justifyContent: "center", color: "black", borderRadius: "5px" }}>+</span>
</div>
</h5>
</div>
</div>
</List.Item>
))}
</List>
</div>
<div className='footer'>
<div id="cart">
<Badge content={cartList.reduce((num, a) => { num += a.num; return num }, 0)}>
<svg t="1681562360047" className="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3777" width="42" height="42"><path d="M757.8624 953.4976H271.616c-107.264 0-194.2016-86.9376-194.2016-194.2016V272.9984c0-107.264 86.9376-194.2016 194.2016-194.2016h486.2464c107.264 0 194.2016 86.9376 194.2016 194.2016v486.2464c0 107.264-86.9376 194.2528-194.2016 194.2528z" fill="#F78748" p-id="3778"></path><path d="M786.8416 757.0432H429.5168c-46.4896 0-85.4016-33.3312-92.5696-79.2576L276.4288 290.56a30.65344 30.65344 0 0 0-30.464-26.0608h-22.3232c-14.1312 0-25.6-11.4688-25.6-25.6s11.4688-25.6 25.6-25.6h22.3232c40.6528 0 74.752 29.184 81.0496 69.3248l60.4672 387.2256a42.24 42.24 0 0 0 41.984 35.9424h357.3248c14.1312 0 25.6 11.4688 25.6 25.6s-11.4176 25.6512-25.5488 25.6512z" fill="#FFFFFF" p-id="3779"></path><path d="M454.1952 639.7952c-13.4144 0-24.6784-10.4448-25.5488-24.0128a25.56928 25.56928 0 0 1 23.9616-27.136l288.8704-18.1248a18.69312 18.69312 0 0 0 17.3056-15.5648l33.2288-195.4304c1.28-7.4752-2.048-12.7488-4.1472-15.2576-2.0992-2.5088-6.7584-6.656-14.336-6.656h-361.472c-14.1312 0-25.6-11.4688-25.6-25.6s11.4688-25.6 25.6-25.6h361.472c20.6336 0 40.1408 9.0624 53.4528 24.832 13.312 15.7696 18.9952 36.5056 15.5136 56.832l-33.2288 195.4304a69.65248 69.65248 0 0 1-64.5632 58.0608l-288.8704 18.1248c-0.5632 0.1024-1.1264 0.1024-1.6384 0.1024z" fill="#FFFFFF" p-id="3780"></path><path d="M407.3472 821.8624m-34.9184 0a34.9184 34.9184 0 1 0 69.8368 0 34.9184 34.9184 0 1 0-69.8368 0Z" fill="#FFFFFF" p-id="3781"></path><path d="M738.1504 821.8624m-34.9184 0a34.9184 34.9184 0 1 0 69.8368 0 34.9184 34.9184 0 1 0-69.8368 0Z" fill="#FFFFFF" p-id="3782"></path></svg>
</Badge>
</div>
<div>
总价:<span style={{ color: "red" }}>¥ {cartList.reduce((num, a) => { num += a.price * a.num; return num }, 0)}</span>
</div>
<div onClick={handleGoods} style={{ background: cartList.reduce((num, a) => { num += a.price * a.num; return num }, 0) !== 0 ? "orange" : "" }}>去结算</div>
</div>
</div>
</div>
<Popup
visible={visible1}
onMaskClick={() => {
setVisible1(false)
}}
bodyStyle={{ height: '60vh' }}
>
<div style={{ overflow: "auto", height: "100%" }}>
<List header='购物车'>
{cartList.map(user => (
<List.Item
key={user.name}
prefix={
<Image
src={user.avatar}
style={{ borderRadius: 20 }}
fit='cover'
width={60}
height={60}
/>
}
description={user.description}
>
<div className='list-content'>
<h4 style={{ color: "black" }}>{user.name}</h4>
<div>
<h5 style={{ display: "flex", justifyContent: "space-between" }}>
<span style={{ color: "red" }}>¥{user.price}</span>
<div style={{ display: "flex" }}>
<div style={{ display: "flex" }}>
<span onClick={() => { handleNum(user, "jian") }} style={{ boxSizing: "border-box", display: "block", width: "20px", height: "20px", background: "white", border: "1px solid orange", display: "flex", alignItems: "center", justifyContent: "center", color: "black", borderRadius: "5px" }}>-</span>
<div style={{ margin: "0px 5px", color: "black" }}>{user.num}</div>
</div>
<span onClick={(e) => { add(e, user) }} style={{ display: "block", width: "20px", height: "20px", background: "orange", display: "flex", alignItems: "center", justifyContent: "center", color: "black", borderRadius: "5px" }}>+</span>
</div>
</h5>
</div>
</div>
</List.Item>
))}
</List>
</div>
</Popup>
</div>
)
}
react如何实现美团加入购物车美团效果
最新推荐文章于 2023-11-25 09:24:22 发布