本身在工做之餘寫的一個商場Demo,用的react+Antd,後端使用的是nodejs,數據庫是mysql,這邊只介紹使用redux對購物車的操做,也並不會對redux的使用進行解釋。node
store.jsmysql
import { createStore, compose, applyMiddleware } from 'redux'; import thunk from 'redux-thunk'; // 處理異步請求的數據,它容許你的action能夠返回函數 import getWantData from './reducers'; const store = createStore(getWantData, compose( applyMiddleware(thunk) )); export default store;
visibility.jsreact
export const SELECT_ALL_SHOP = 'SELECT_ALL_SHOP'; // 購物車全部商品 export const GET_USER_CART = 'GET_USER_CART'; // 用戶購物車數據 export const TOGGLE_SHOP = 'TOGGLE_SHOP'; // 是否選中商品 export const ADD_SHOP = 'ADD_SHOP'; // + 商品 export const SUB_SHOP = 'SUB_SHOP'; // — 商品 export const REMOVE_SHOP = 'REMOVE_SHOP'; // 刪除商品
action.jsgit
import { SELECT_ALL_SHOP, GET_USER_CART, TOGGLE_SHOP, ADD_SHOP, SUB_SHOP, REMOVE_SHOP } from './visibility'; import { wantShopData } from '../api/shopApi'; // 同步獲取用戶購物車全部數據 export function asyncUserCartData(userCartData){ let cartData = userCartData.map(item => { item.isSelected = true; // 經過該屬性判斷該條商品是否處於選中狀態 return item; }); return { type: GET_USER_CART, userCartData: cartData } } // 異步獲取用戶購物車數據 export function getUserCarData(userId) { let statements = `SELECT * FROM userCart WHERE user_id = '${userId}'`; return (dispatch) => { wantShopData({ statements }).then(data => { dispatch(asyncUserCartData(data)); }); } } // 購物車選中或不選中 export function checkShopNumber(type, shopId) { return { type: TOGGLE_SHOP, shopId }; } // 購物車全選或取消全選 export function operationAllShop(seleStatus) { return { type: SELECT_ALL_SHOP, seleStatus }; } // 購物車加商品 export function userAddShop(shopId) { return { type: ADD_SHOP, shopId } } // 購物車減商品 export function userSubShop(shopId) { return { type: SUB_SHOP, shopId } } // 刪除商品 export function removeCartShop(shopId) { return { type: REMOVE_SHOP, shopId } }
一開始購物車的商品都是默認選中的,由於上面的isSelected一開始就是true,如今要實現的就是商品在選中狀態下對於商品數量的變化實現對下面總價的相應變化,注意,首先是隻有選中狀態下點擊➕或➖操做下面全部的商品總價會變,而單個商品的總價是不受選中這個狀態影響的,其次要是在未選中狀態下改變單個商品數量,選中後全部商品總價跟着改變,還有就是刪除選中的商品後改變總總價和總數量,最後實現全選和取消全選功能github
整個相當重要的一步就是先獲取購物車裏的所有數據sql
首先定義好mapStateToProps和mapDispatchToProps函數,這裏使用了react-redux裏的connect數據庫
import { isLogin, getUserId } from "../../comment/methods/util"; import { getUserCarData } from '../../reduxs/action'; function mapStateToProps(state) { return { cartShopData: state.userCartData }; } function mapDispatchToProps(dispatch) { return { userCartDataFn(userId) { dispatch(getUserCarData(userId)); // 觸發action } } } if(isLogin()) { // 判斷登陸後獲取 this.props.userCartDataFn(getUserId()); }esle { // 沒有登陸即跳往登陸頁 } // 使用componentWillReceiveProps監測props的變化 // reducers.js case GET_USER_CART: // 獲取購物車全部數據 return [ ...action.userCartData ];
獲取到購物車所有數據後實現單個商品的選中及取消選中、刪除商品redux
function mapDispatchToProps(dispatch) { return { shopTotalFn(type, shopId) { // 商品的選中或取消選中 dispatch(checkShopNumber(type, shopId)); }, removeShop(shopId) { // 刪除商品 dispatch(removeCartShop(shopId)); } } } // 商品的刪除 <!--<Button type="danger" onClick={ () => { this.props.removeShop(this.state.singData.shop_id); } }>刪除 </Button>--> // 商品的選中事件selectCheckFn selectCheckFn() { this.props.shopTotalFn(TOGGLE_SHOP, this.state.singData.shop_id); } // reducers.js case REMOVE_SHOP: // 移除該商品 let remainShop = state.filter(item => item.shop_id !== action.shopId); return [ ...remainShop ]; case TOGGLE_SHOP: // 選中或取消選中商品 state.map(item => { if(action.shopId === item.shop_id) { item.isSelected = !item.isSelected; } }); return [ ...state ];
商品數量的加減後端
這邊得注意商品的選中狀態,選中後改變單總價和總總價,未選中只改變單總價api
function mapDispatchToProps(dispatch) { return { addShopNum(shopId) { dispatch(userAddShop(shopId)); }, subShopNum(shopId) { dispatch(userSubShop(shopId)); } } } reducShopNum() { // 商品減操做 if(this.state.shopNum > 1) { this.props.subShopNum(this.props.data.shop_id); this.state.shopNum --; this.setState({ shopNum: this.state.shopNum }, () => { this.props.onChange(this.state.shopNum, this.state.shopPrice); }); } } addShopNum() { // 商品加操做 this.props.addShopNum(this.props.data.shop_id); this.state.shopNum ++; this.setState({ shopNum: this.state.shopNum }, () => { this.props.onChange(this.state.shopNum, this.state.shopPrice); }); } // reducers.js case ADD_SHOP: // 商品 ++ state.map(item => { if(item.shop_id === action.shopId) { item.shop_val ++; } }); return [ ...state ]; case SUB_SHOP: // 商品 -- state.map(item => { if(item.shop_id === action.shopId) { item.shop_val --; } }); return [ ...state ];
最後就是商品的全選和取消全選了
function mapDispatchToProps(dispatch) { return { selectStatus(seleStatus) { dispatch(operationAllShop(seleStatus)) } } } selectAllShop() { if(this.state.optxt === '全 選') { this.props.selectStatus('SELECTED_S'); this.setState({ optxt: '取消全選' }); }else { this.props.selectStatus('CANCEL_S'); this.setState({ optxt: '全 選' }); } } // reducers.js case SELECT_ALL_SHOP: // 選中或取消選中全部商品 if(action.seleStatus === 'SELECTED_S') { state.map(item => { item.isSelected = true; }); } if(action.seleStatus === 'CANCEL_S') { state.map(item => { item.isSelected = false; }); } return [ ...state ];
這樣購物車基本的操做功能也就都實現了,想看完整代碼的能夠 點擊一下 進行查看
總結一下:使用了redux後,在購物車操做中確實方便了不少,因爲全部的操做都是對一開始的惟一數據源進行操做,從而使思惟更加的清晰明確。