您的位置:首页 > 其它

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 使用即可

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: