React列表欄及購物車組件使用詳解
本文實例為大傢分享瞭React列表欄及購物車組件的具體代碼,供大傢參考,具體內容如下
一、組件介紹
商傢詳細界面(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]){ // 在滑動的時候取其數組中的第某個集合並且修改索引值 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; // 循環遍歷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] } // 調用子組件Cart裡的強制刷新方法,在AddCut組件裡執行方法 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)=>{ // 產生一個對象集合 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=()=>{ // 讀取數據 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">去結算</div> </div> ); } } export default Cart;
二、效果展示
以上就是本文的全部內容,希望對大傢的學習有所幫助,也希望大傢多多支持WalkonNet。
推薦閱讀:
- react分頁顯示數據的方法
- react實現移動端二級路由嵌套詳解
- React setState是異步還是同步原理解析
- 代碼解析React中setState同步和異步問題
- React Class組件生命周期及執行順序