第一步:获取小球要飞的盒子中
//获取小求要飞到那个盒子中
const BOX = useRef();
const GetBox =()=>BOX.current
定义的盒子
<div className='footer' ref={BOX}>
<div className='six' >
<Badge content={count1}>
<Bill/>
</Badge>
¥{num}.0<span className='span1'>配送费¥3.2</span>
</div>
<div className='menu' onClick={() => {
navigate('/app/account')
}}>去下单</div>
</div>
第二步:创建小球 这里的创建小球函数接收两个参数 分别为 当我们点击添加按钮时候的X和Y轴坐标
let createBall = (left,top)=>{
let Ball = document.createElement('div');
Ball.style.position = 'absolute';
Ball.style.left = left + 'px';
Ball.style.top = (top-10) + '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 = GetBox().offsetLeft + GetBox().offsetWidth / 2 + 'px';
Ball.style.top = GetBox().offsetTop + "px";
},0)
Ball.ontransitionend = function(){
Ball.remove();
}
}
第三步:在添加方法中 我们传递一个ev事件对象 然后通过这个ev事件对象获取到当前点击的X轴Y轴坐标的值 并且传递给我们的创建小球函
const Add = (e)=>{
let x = e.clientX
let y = e.clientY
createBall(x,y)
}
第五步:在点击的按钮调用这个add函数
<span onClick={(e)=>{
Add(e)
}}>¥{item.price}/份
<Stepper
min={0}
value={item.num}
onChange={v => {
let { data } = axios.put("/updatemenu", { _id: item._id, num: v })
getArr()
setValue9(v)
setPrice(item.price)
}} />
</span>
最后就OK了
总的代码如下:
import React, { useState, useEffect, useRef, useMemo } from 'react'
import { Bill } from '@react-vant/icons';
import { Sidebar, Stepper, Badge } from 'react-vant';
import { useNavigate } from 'react-router-dom';
import './Menu.scss';
import axios from 'axios';
axios.defaults.baseURL = 'http://locahost:3000';
export default function Menu() {
//获取小求要飞到那个盒子中
const BOX = useRef();
const GetBox =()=>BOX.current
let createBall = (left,top)=>{
let Ball = document.createElement('div');
Ball.style.position = 'absolute';
Ball.style.left = left + 'px';
Ball.style.top = (top-10) + '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 = GetBox().offsetLeft + GetBox().offsetWidth / 2 + 'px';
Ball.style.top = GetBox().offsetTop + "px";
},0)
Ball.ontransitionend = function(){
Ball.remove();
}
}
const Add = (e)=>{
let x = e.clientX
let y = e.clientY
createBall(x,y)
}
const [active, setActive] = useState('660a5bf3dd5d7cc8b83b08e5');
const navigate = useNavigate()
const [value9, setValue9] = useState(0)
const [price, setPrice] = useState(0)
const [arr, setArr] = useState([])
const [type, setType] = useState([])
let num = useMemo(() => {
let nums = 0
return arr.reduce((a, item) => {
return nums += item.num * item.price
}, 0)
}, [arr])
let count1 = useMemo(()=>{
return arr.reduce((a,item)=>{
return a += item.num
},0)
},[arr])
useEffect(() => {
getArr()
getType()
}, [])
let getArr = async () => {
let { data } = await axios.get('/listmenu')
setArr(data.menus)
}
let getType = async () => {
let { data } = await axios.get('/listtype')
setType(data.types)
}
return (
<div id='nav'>
<div>
<div className='top1'> 外卖点餐</div>
<div className='content'>
<div>
<b>徐先生私房菜(天河店)</b>
距离1.0km</div>
<div>
<button className='btn1'>堂食</button>
<button className='btn2'>外卖</button>
</div>
</div>
</div>
<div className='menu-sidebar'>
<Sidebar>
{
type.map(item =>
<Sidebar.Item contentStyle={{ backgroundColor: '#fff' }}
onClick={() => {
setActive(item._id)
}} key={item._id} title={item.name}>
{
arr.filter(item => item.cid === active).map(item =>
<div key={item._id} className='box1'>
<div>
<img src={item.img} alt="" className='img1' />
</div>
<div className='right' >
<b>{item.title}</b>
<b className='org'>4.5折</b>
<span onClick={(e)=>{
Add(e)
}}>¥{item.price}/份
<Stepper
min={0}
value={item.num}
onChange={v => {
let { data } = axios.put("/updatemenu", { _id: item._id, num: v })
getArr()
setValue9(v)
setPrice(item.price)
}}
/>
</span>
</div>
</div>)
}
</Sidebar.Item>
)}
</Sidebar>
</div>
<div className='footer' ref={BOX}>
<div className='six' >
<Badge content={count1}>
<Bill/>
</Badge>
¥{num}.0<span className='span1'>配送费¥3.2</span>
</div>
<div className='menu' onClick={() => {
navigate('/app/account')
}}>去下单</div>
</div>
</div>
)
}