React列表欄及購物車組件使用詳解
本文實例為大家分享了React列表欄及購物車組件的具體代碼,供大家參考,具體內(nèi)容如下
一、組件介紹
商家詳細界面(StoreDetail組件):
import React from 'react'; import axios from 'axios'; import GoBack from '../smallPage/GoBack'; import '../../Assets/css/storeDetail.css'; import MenuList from '../../Mock/MenuList'; import Order from '../menuPage/Order'; import Evaluate from '../menuPage/Evaluate'; import Business from '../menuPage/Business'; class StoreDetail extends React.Component { constructor(props) { super(props); this.state = { food:null, menulist:MenuList }; } componentDidMount(){ axios.get("/food").then((res)=>{ this.setState({ food:res.data.result.data }); console.log(this.state.food); }); } userSelect=(index)=>{ MenuList.forEach((val,key)=>{ val.isshow=false; if(key===index){ val.isshow=true; } }); this.setState({ menulist:MenuList }); } render() { return ( this.state.food? <div> <GoBack title={this.state.food.poi_info.name}/> <div className="foodimage"> <img src={this.state.food.poi_info.pic_url} alt=""/> <img src={this.state.food.poi_info.head_pic_url} alt=""/> <span>{this.state.food.poi_info.name}</span> </div> <div> <ul className="menulist"> { this.state.menulist.map((value,index)=>{ return ( <li key={index} onClick={this.userSelect.bind(this,index)}> {value.title} <span className={value.isshow?'foodline':''}></span> </li> ) }) } </ul> </div> { this.state.menulist.map((value,index)=>{ if(value.isshow&&index===0){ return <Order toprice={this.state.food.poi_info.shipping_fee_tip} orderlist={this.state.food.food_spu_tags} key={index}/> }else if(value.isshow&&index===1){ return <Evaluate key={index}/> }else if(value.isshow&&index===2){ return <Business key={index}/> }else{ return ''; } }) } </div> :'' ); } } export default StoreDetail;
點單界面(Order組件):
import React from 'react'; import '../../Assets/css/order.css'; import AddCut from '../smallPage/AddCut'; import Cart from '../smallPage/Cart'; class Order extends React.Component { constructor(props) { super(props); this.state = { list:[], leftindex:0 }; } scrollRight=(e)=>{ let scrolltop=e.target.scrollTop; let listheight=this.state.list; for(let i=0;i<listheight.length-1;i++){ if(scrolltop<listheight[i]){ // 在滑動的時候取其數(shù)組中的第某個集合并且修改索引值 this.setState({ leftindex:i }); break; }else if(scrolltop>=listheight[i]&&scrolltop<listheight[i+1]){ // 當右邊滑動值大于整個高的一半時,左邊的索引需要往下走 if(i+1>=listheight.length/2){ // 獲取左邊的ul,讓其scrollTop往下頂 this.refs.leftul.scrollTop=listheight[i+1]; }else{ // 讓其scrollTop往上頂 this.refs.leftul.scrollTop=0; } this.setState({ leftindex:i+1 }); break; } } } // 用戶點擊時,讓當前索引變色 userClick=(index)=>{ this.setState({ leftindex:index }); this.refs.order_scroll.scrollTop=index-1>=0?this.state.list[index-1]:0; } componentDidMount(){ let order_block=document.getElementsByClassName("order_block"); let listinfo=this.state.list; // 循環(huán)遍歷div,拿到每個div的偏移量,再將其push進this.state中進行修改顯示,修改后得到listinfo // 若為第一個div,則只拿其自身的偏移量;否則,則拿其自身+listinfo[i-1]的偏移量 for(let i=0;i<order_block.length;i++){ if(i===0){ listinfo.push(order_block[i].offsetHeight); }else{ listinfo.push(order_block[i].offsetHeight+listinfo[i-1]); } } this.setState({ list:listinfo }); // console.log(listinfo); (11) [550, 612, 1284, 1712, 2628, 5496, 7083, 8609, 9099, 9465, 10747] } // 調(diào)用子組件Cart里的強制刷新方法,在AddCut組件里執(zhí)行方法 refComponent=()=>{ let ele=this.refs.cart; ele.update(); } render() { return ( <div className="order"> <div className="order_left"> <ul ref="leftul"> { this.props.orderlist.map((value,index)=>{ return ( // 按照索引來判斷左邊li的顏色 <li onClick={this.userClick.bind(this,index)} className={this.state.leftindex===index?'leftli leftli_color':'leftli'} key={index}> <img src={value.icon} alt=""/> <span>{value.name}</span> </li> ) }) } </ul> </div> <div onScroll={this.scrollRight} className="order_right"> <div ref="order_scroll" className="order_scroll"> { this.props.orderlist.map((value,index)=>{ return ( <div className="order_block" key={index}> <ul> { value.spus.map((v,k)=>{ return ( <li key={k}> <div className="order_block_img"> <img src={v.picture} alt=""/> </div> <div className="order_block_word"> <div className="order_block_word_name">{v.name}</div> <div className="order_block_word_zan">{v.praise_content}</div> <div className="order_block_word_price"> <span>¥{v.min_price}</span>/份 <AddCut parent={this} name={v.name} price={v.min_price}/> </div> </div> </li> ) }) } </ul> </div> ) }) } </div> </div> <Cart ref="cart" toprice={this.props.toprice}/> </div> ); } } export default Order;
加減頁面(AddCut組件):
import React from 'react'; import '../../Assets/css/addCut.css'; import CartData from '../../Mock/CartData'; class AddCut extends React.Component { constructor(props) { super(props); this.state = { num:0 }; } userAdd=()=>{ let addnum=this.state.num; addnum++; this.setState({ num:addnum }); this.addCart(addnum); this.props.parent.refComponent(); } userCut=()=>{ let cutnum=this.state.num; cutnum--; if(cutnum<0){ cutnum=0; } this.setState({ num:cutnum }); this.addCart(cutnum); this.props.parent.refComponent(); } addCart=(num)=>{ // 產(chǎn)生一個對象集合 let list={ name:this.props.name, price:this.props.price, num:num }; let same=false; if(CartData.length===0){ CartData.push(list); } for(let i=0;i<CartData.length;i++){ if(CartData[i].name===this.props.name){ CartData[i].num=num; same=true; } } if(!same){ CartData.push(list); } } render() { return ( <div className="addcut"> <img onClick={this.userCut} className={this.state.num>0?'show':'showhidden'} src={require("../../Assets/image/minus.edae56b865f90527f2657782f67d9c3e.png")} alt=""/> <span className={this.state.num>0?'show':'showhidden'}>{this.state.num}</span> <img onClick={this.userAdd} src={require("../../Assets/image/plus.af10af5a9cee233c612b3cff5c2d70cd.png")} alt=""/> </div> ); } } export default AddCut;
購物車頁面(Cart組件):
import React from 'react'; import '../../Assets/css/cart.css'; import CartData from '../../Mock/CartData'; class Cart extends React.Component { constructor(props) { super(props); this.state = { cart:[], totalprice:0 }; } update=()=>{ // 讀取數(shù)據(jù) this.setState({ cart:CartData }); // 計算總價 let prices=0; for(let i=0;i<CartData.length;i++){ prices+=CartData[i].price*CartData[i].num; } this.setState({ totalprice:prices }); } render() { return ( <div className="cart"> <div className="cart_left"> <img src={require("../../Assets/image/shop-icon.3a615332a0e634909dc3aa3a50335c8f.png")} alt=""/> <span>¥{this.state.totalprice}</span><br/> <span>另需{this.props.toprice}</span> </div> <div className="cart_right">去結(jié)算</div> </div> ); } } export default Cart;
二、效果展示
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
關(guān)于useEffect的第二個參數(shù)解讀
這篇文章主要介紹了關(guān)于useEffect的第二個參數(shù),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-09-09webpack4+react多頁面架構(gòu)的實現(xiàn)
webpack在單頁面打包上應(yīng)用廣泛,以create-react-app為首的腳手架眾多。這篇文章主要介紹了webpack4+react多頁面架構(gòu)的實現(xiàn),具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-10-10react-native 封裝視頻播放器react-native-video的使用
本文主要介紹了react-native 封裝視頻播放器react-native-video的使用,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2023-01-01React?Hook中的useEffecfa函數(shù)的使用小結(jié)
React 會在組件更新和卸載的時候執(zhí)行清除操作, 將上一次的監(jiān)聽取消掉, 只留下當前的監(jiān)聽,這篇文章主要介紹了React?Hook?useEffecfa函數(shù)的使用細節(jié)詳解,需要的朋友可以參考下2022-11-11react echarts tooltip 區(qū)域新加輸入框編輯保存數(shù)據(jù)功能
這篇文章主要介紹了react echarts tooltip 區(qū)域新加輸入框編輯保存數(shù)據(jù)功能,大概思路是用一個div包裹echarts, 然后在echarts的同級新建一個div用來用來模擬真實tooltip,通過鼠標移入移出事件控制真實tooltip的顯示與隱藏,需要的朋友可以參考下2023-05-05react實現(xiàn)同頁面三級跳轉(zhuǎn)路由布局
這篇文章主要為大家詳細介紹了react實現(xiàn)同頁面三級跳轉(zhuǎn)路由布局,一個路由小案例,具有一定的參考價值,感興趣的小伙伴們可以參考一下2019-09-09React 如何使用時間戳計算得到開始和結(jié)束時間戳
這篇文章主要介紹了React 如何拿時間戳計算得到開始和結(jié)束時間戳,本文通過示例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-09-09React?Fiber?樹思想解決業(yè)務(wù)實際場景詳解
這篇文章主要為大家介紹了React?Fiber?樹思想解決業(yè)務(wù)實際場景詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-12-12