RN的购物车实现( 数量,单价,总价,总数 )
2017-07-01 11:07
609 查看
1. 导入 JSON 数据: (data.json)
[ { "id": "1", "image": "a", "money": "39", "name": "\u5fb7\u56fdOETTINGER\u5965\u4e01\u683c\u5927\u9ea6\u5564\u9152500ml*4\u7f50\/\u7ec4" }, { "id": "2", "image": "b", "money": "40", "name": "\u5fb7\u62c9\u514b\uff08Durlacher\uff09 \u9ed1\u5564\u9152 330ml*6\u542c" }, { "id": "3", "image": "c", "money": "109", "name": "\u5965\u5854\u5229\u91d1\u7235 \u5564\u9152500ml*12 \u5308\u7259\u5229\u539f\u88c5\u4f4e\u5ea6\u8fdb\u53e3\u5564\u9152\u9152\u6c34\u996e\u54c1" }, { "id": "4", "image": "d", "money": "158", "name": "\u5fb7\u56fd\u5564\u9152 \u539f\u88c5\u8fdb\u53e3\u5564\u9152 flensburger\/\u5f17\u4f26\u65af\u5821\u5564\u9152 \u571f\u8c6a\u91d1\u5564 5L \u6876\u88c5\u5564\u9152" }, { "id": "5", "image": "e", "money": "66", "name": "\u9752\u5c9b\u 4000 5564\u9152 \u7ecf\u5178 \u9187\u539a \u5564\u9152500ml*12\u542c\/\u7bb1 \u56fd\u4ea7 \u6574\u7bb1" }, { "id": "6", "image": "f", "money": "140", "name": "\u4eac\u59ff \u767e\u5a01\u7f50\u88c5330ml*24 \u5564\u9152" }, { "id": "7", "image": "g", "money": "58", "name": "\u5fb7\u56fdOETTINGER\u5965\u4e01\u683c\u81ea\u7136\u6d51\u6d4a\u578b\u5c0f\u9ea6\u5564\u9152500ml*4\u7f50\/\u7ec4" }, { "id": "8", "image": "h", "money": "695", "name": "Martell\u9a6c\u7239\u5229\u540d\u58eb1000ML \u8fdb\u53e3\u6d0b\u9152 \u540d\u4ed5\u5e72\u9091\u767d\u5170\u57301L" }, { "id": "9", "image": "i", "money": "108", "name": "\u5965\u7f8e\u52a0\u94f6\u9f99\u820c\u5170\u3010OLMECA TEQUILA\u301138% 750ml" }, { "id": "10", "image": "j", "money": "1386", "name": "\u4eba\u5934\u9a6c\u5929\u9187XO\u7279\u4f18\u9999\u69df\u5e72\u9091\u767d\u5170\u5730700ml" }, { "id": "11", "image": "k", "money": "1080", "name": "40\u00b0\u6cd5\u56fd\u9a6c\u7239\u5229\u84dd\u5e26\u5e72\u9091\u767d\u5170\u5730700ml" }, { "id": "12", "image": "l", "money": "598", "name": "\u6c99\u7687\u4f0f\u7279\u52a0\u585e\u73de700ml\u9650\u91cf\u7248" }, { "id": "13", "image": "m", "money": "92", "name": "\u767e\u52a0\u5f97\u9ed1\u6717\u59c6\u9152 \u70c8\u9152 750ml" }, { "id": "14", "image": "n", "money": "99", "name": "Seagrams Gin 750ML 40\u5ea6" }, { "id": "15", "image": "o", "money": "1060", "name": "\u9a6c\u7239\u5229\u84dd\u5e26\u5e72\u9091\u767d\u5170\u5730 700ml" }, { "id": "16", "image": "p", "money": "158", "name": "\u5f20\u88d5\u89e3\u767e\u7eb3\u5e72\u7ea2\u8461\u8404\u9152\u53cc\u652f\u793c\u76d2 750ml*2" }, { "id": "17", "image": "q", "money": "1230", "name": "\u7231\u4e4b\u6e7e+\u5170\u8d35\u4eba\u7ec4\u5408" }, { "id": "18", "image": "r", "money": "138", "name": "\u83f2\u5361\u73cd\u85cf\u838e\u5f53\u59ae\u8461\u8404\u9152750ml" }, { "id": "19", "image": "s", "money": "1580", "name": "\u62c9\u56fe\u5609\u5229\u5e84\u56ed\u5e72\u7ea2\u8461\u8404\u9152" }, { "id": "20", "image": "t", "money": "1890", "name": "\u62a5\u6069\u57ce\u5821\u5e72\u7ea2\u8461\u8404\u9152 \u516d\u652f\u88c5" }, { "id": "21", "image": "x", "money": "2360", "name": "\u8c6a\u514b\u739b\u6b4c\u5e84\u56ed\u5e72\u7ea2\u8461\u8404\u9152 750ml 1\u652f\u88c5" }, { "id": "22", "image": "y", "money": "98", "name": "\u767d\u6d6a\u838e\u5e84\u56ed\u5e72\u7ea2\u8461\u8404\u9152 750ml" } ]
2. 设置底部的总计 View ( XZHBottomView.js )
import React, { Component } from 'react'; import { AppRegistry, StyleSheet, Text, View, TouchableOpacity, Image, ScrollView, DeviceEventEmitter } from 'react-native'; var Dimensions = require('Dimensions'); var {width, height} = Dimensions.get('window'); class XZHBottomView extends Component{ // 构造 constructor(props) { super(props); // 初始状态 this.state = { // 购买商品总金额 totalPrice: 0, // 购买的酒数组 buyWineArr: [] }; } render(){ return( <View style={styles.viewStyle}> <View style={styles.leftView}> <Text style={{fontSize:18}}>总价:</Text> <Text style={{fontSize:18, color:'red'}}>¥{this.state.totalPrice}</Text> </View> <View style={styles.rightView}> <TouchableOpacity onPress={()=>this._buy()}> <Text style={{fontSize:16, marginRight:5}}>购买</Text> </TouchableOpacity> <TouchableOpacity onPress={()=>this._clearGoods()}> <Text style={{fontSize:16, color:'red'}}>清空购物车</Text> </TouchableOpacity> </View> </View> ) } /** * 点击购买 * @private */ _buy() { var buyString = '您购买的商品清单: \n'; this.state.buyWineArr.forEach((value, index)=>{ buyString += '(' + (index+1) + ') 商品ID:' + value.id + ', 单价:' + value.money + ', 购买数量' + value.buyNum + '\n'; }); alert(buyString + '\n' + '总价:' + this.state.totalPrice + '元'); } /** * 清空购物车 * @private */ _clearGoods() { // 1. 删除购物车中所有商品 const buyWineArr = this.state.buyWineArr; buyWineArr.splice(0, buyWineArr.length); // 2. 更新状态,刷新UI this.setState({ buyWineArr: buyWineArr, totalPrice: 0 }) // 3. 通知界面刷新 DeviceEventEmitter.emit('refreshList', null); } componentDidMount() { this.notice = DeviceEventEmitter.addListener('changeTotalPrice', (wine)=>{ // 1. 深拷贝一个新对象 var tempWine = JSON.parse(JSON.stringify(wine)); // 2. 判断 var tempWineArr = this.state.buyWineArr; tempWineArr.forEach((value, index)=>{ if(value.id == tempWine.id){ tempWineArr.splice(index, 1); } }); if(tempWine.buyNum > 0){ tempWineArr.push(tempWine); } // 3. 计算总价 var totalPrice = 0; tempWineArr.forEach((value, index)=>{ totalPrice += value.buyNum * value.money }); // 4. 更新状态,刷新UI this.setState({ totalPrice: totalPrice, buyWineArr: tempWineArr }) }); } componentWillUnMount() { this.notice.remove(); } } const styles = StyleSheet.create({ viewStyle:{ flexDirection: 'row', height:44, borderTopWidth:1, borderTopColor:'#999', justifyContent:'space-between', alignItems:'center', backgroundColor:'#ccc', position:'absolute', bottom: 50, width: width }, leftView:{ flexDirection:'row', marginLeft: 8 }, rightView:{ ce8c flexDirection:'row', marginRight: 8 } }); module.exports = XZHBottomView;
3.cellView 的布局 ( XZHWineCell.js )
import React, { Component, PropTypes } from 'react'; import { AppRegistry, StyleSheet, Text, View, TouchableOpacity, Image, ScrollView, InteractionManager, DeviceEventEmitter } from 'react-native'; var Dimensions = require('Dimensions'); var {width, height} = Dimensions.get('window'); class XZHWineCell extends Component{ // 构造 constructor(props) { super(props); // 初始状态 this.state = { wine: this.props.wine }; } render(){ var wine = this.state.wine; return( <TouchableOpacity style={styles.viewStyle}> {/*左边*/} <TouchableOpacity style={styles.leftView}> <Image source={{uri: wine.image}} style={styles.leftImageStyle}/> <View style={{width:width * 0.7}}> <Text style={styles.titleStyle} numberOfLines={1} > {wine.name} </Text> <Text>¥{wine.money}</Text> </View> </TouchableOpacity> {/*右边*/} <View style={styles.rightView}> <TouchableOpacity onPress={()=>this._removeWine(wine)}> <Text style={[{fontSize:20}, styles.circleStyle]}>-</Text> </TouchableOpacity> <Text style={{fontSize:20, margin: 10}}>{wine.buyNum}</Text> <TouchableOpacity onPress={()=>this._addWine(wine)}> <Text style={[{fontSize:20}, styles.circleStyle]}>+</Text> </TouchableOpacity> </View> </TouchableOpacity> ) } componentWillUpdate(nextProps) { // 接收通知 this.notice = DeviceEventEmitter.addListener('refreshList', ()=>{ // 1. 购买数量清零 const tempWine = this.state.wine; tempWine.buyNum = 0; this.setState({ wine: tempWine }) }); } componentDidUnMount() { // 移除通知 this.notice.remove(); } /** * 移除商品 */ _removeWine(wine){ // 1.判断 if(wine.buyNum == 0){ alert('商品数量不能小于0'); return; } // 2. 改变数量 wine.buyNum --; this.setState({ wine: wine }); // 3. 发出通知 this._changeTotalPrice(wine); } /** * 添加商品 */ _addWine(wine){ // 1. 改变数量 wine.buyNum ++; this.setState({ wine: wine }); // 2. 发出通知 this._changeTotalPrice(wine); } /** * 发出通知 * @param wine 购买的商品 * @private */ _changeTotalPrice(wine){ DeviceEventEmitter.emit('changeTotalPrice', wine); } } const styles = StyleSheet.create({ viewStyle:{ flexDirection:'row', backgroundColor:'#fff', borderBottomWidth:1, borderBottomColor: '#ccc' }, leftView:{ width: width * 0.7, flexDirection:'row', overflow:'hidden', alignItems:'center' }, leftImageStyle: { width: 60, height: 60, margin: 5 }, rightView: { width: width * 0.3, flexDirection: 'row', justifyContent:'center', alignItems:'center' }, titleStyle:{ width: 0.5 * width }, circleStyle:{ width: 30, height: 30, borderRadius: 15, borderWidth:1, borderColor:'red', textAlign:'center', alignItems:'center', color:'blue', fontWeight:'900' } }); module.exports = XZHWineCell;
4. 购物车页面 ( XZHMain.js )
/** * Sample React Native App * https://github.com/facebook/react-native * @flow */ /* * 案例博客 : http://yiweifen.com/html/news/WaiYu/105343.html * */ import React, {Component} from 'react'; import { AppRegistry, StyleSheet, Text, View, ListView, DeviceEventEmitter } from 'react-native'; import XZHBottomView from './XZHBottomView'; import XZHWineCell from './XZHWineCell'; var data = require('./data.json'); export default class extends Component { // 构造 constructor(props) { super(props); // 创建数据源 var ds = new ListView.DataSource({ rowHasChanged: (r1, r2) => r1 !== r2 }); // 初始状态 this.state = { dataArr: data, dataSource: ds }; } render() { return ( <View style={styles.container}> <ListView dataSource={this.state.dataSource} renderRow={(rowData)=> this._renderRow(rowData)} contentInset={{bottom: 44}} /> <XZHBottomView style={styles.bottomViewStyle}/> </View> ); } _renderRow(rowData){ return( <XZHWineCell wine={rowData} /> ) }; componentWillMount() { for (var i = 0; i < data.length; i++) { // 1. 取出单个对象 var item = data[i]; // 2. 定义购买数量 并 插入对象 item.buyNum = 0; } this.setState({ dataSource: this.state.dataSource.cloneWithRows(this.state.dataArr) }); } } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#e8e8e8', }, bottomViewStyle: {} });
5. 引入 XAHMain.js 使用即可
相关文章推荐
- 实现购物车结算功能:批量/全部删除,全选,单价/总价,数量增减,页面隐藏/显示
- 实现购物车结算功能:批量/全部删除,全选,单价/总价,数量增减,页面隐藏/显示
- 实现购物车结算功能:批量和全部删除,全选和反选,单价和总价,数量增减,页面隐藏和显示
- 实现购物车结算功能:批量和全部删除,全选和反选,单价和总价,数量增减,页面隐藏和显示
- AngularJS实现的根据数量与单价计算总价功能示例
- 实现购物车多物品数量的加减+总价计算
- 模仿购物车实现ListView中商品数量的添加以及总价的调整
- JQuery实现购物车数量加减总价累加
- 实现购物车多物品数量 总价计算
- AngularJS—实现根据数量、单价计算总价效果
- jQuery实现购物车多物品数量的加减+总价+删除计算
- jQuery实现购物车多物品数量的加减+总价计算
- jQuery实现购物车多物品数量的加减+总价计算
- jQuery实现购物车物品数量的加减(减到1时不能减少)
- Jquery仿美团外卖等食品选择页面购物车数量加减功能实现
- JS实现总价随数量变化而变化(顾客购买商品表单)
- jQuery实现购物车物品数量的加减并自动计算价格
- ListView实现购物车功能包含单选与多选和修改数量
- 实现购物车商品数量+1、-1按钮的效果