react-native 制作购物车ShopCart

使用 react-native 写的一个 ShopCart 的 demo

目录:

一、index.android.js

// 定义全局变量
global.__APP__ = true; // 用于区分是web应用还是app应用 便于代码多端调用
global.__ANDROID__ = true; // android环境中
global.__IOS__ = false;

// 将所有代码放在src目录下执行,方便android和ios调用
require('./src'); // 如果写的是目录,则默认调用目录下小写的index.js文件

 

二、index.ios.js

// 定义全局变量
global.__APP__ = true; // 用于区分是web应用还是app应用 便于代码多端调用
global.__ANDROID__ = false;
global.__IOS__ = true; // ios 环境中

// 将所有代码放在src目录下执行,方便android和ios调用
require('./src'); // 如果写的是目录,则默认调用目录下小写的index.js文件

 

三、Index.js ( 跳转页 )

import React, { Component } from 'react';
import {
	AppState,
	StyleSheet,
	View,
	Button,
	Text
} from 'react-native';

const INITIAL_ROUTE = {
	location:'/splash',
}

const styles = StyleSheet.create({
	root: {
		flex: 1,
		justifyContent: 'center',
	},
	text: {
		textAlign: 'center',
		fontSize: 18,
	}
});

// 导入ShopCart
import ShopCart from './ShopCart';

export default class App extends Component {
	gotoShopCart = () => {
		// 通过解钩 获取传递的navigator
		const { navigator } = this.props;
		// push方法会经过navigator的renderScene方法
		navigator.push({
			component: ShopCart
		});
	};
	render() {
		return (
			<View style={styles.root}>
				<Text style={styles.text}>这是首页</Text>
				<Button onPress={this.gotoShopCart}>点这里跳转到购物车</Button>
			</View>
		);
	}
}

 

四、ShopCart.js ( 购物车页面 )

/**
 * 购物车
 */
import React, { Component } from 'react';
import {
	AppState,
	StyleSheet,
	View,
	Text
} from 'react-native';

// 引入observer 使静态数据可读写
import { observer } from 'mobx-react/native';
// 引入改造后的数据
import cartData from '../logics/CartData';

// 引入Header
import Header from '../components/Header';
// 引入ItemList
import ItemList from '../components/ItemList';
// 引入Footer
import Footer from '../components/Footer';

const styles = StyleSheet.create({
	root: {
		flex: 1,
	},
});

export default class ShopCart extends Component {
	render() {
		// ShopCart具有navigator
		const { navigator } = this.props;
		return (
			<View style={styles.root}>
				<Header navigator={navigator} />
				<ItemList cartData={cartData} />
				<Footer cartData={cartData} />
			</View>
		);
	}
}

 

五、组件 

1. Circle.js

/**
 * 勾选框组件
 */
import React, { Component } from 'react';
import {
	StyleSheet,
	TouchableOpacity
} from 'react-native';

const styles = StyleSheet.create({
	select: {
		height: 20,
		width: 20,
		borderRadius: 10,
		borderColor: '#000',
		borderWidth: StyleSheet.hairlineWidth,
	},
	checked: {
		backgroundColor: '#f23030',
	},
});

export default class Circle extends Component {
	select = () => {
		// 通过props,从父组件取出onPress
		const { onPress } = this.props;
		// 赋值
		let { checked } = this.state;
		// 值相等的情况,es6的简写 checked:checked,只写一个checked,
		this.setState({
			checked,
		});
		// 判断onPress是否存在,存在则执行下面的代码
		onPress && onPress(checked);
	};
	state = {
		checked: false,
	};
	render() {
		<TouchableOpacity
			style={[styles.select, this.state.checked && styles.checked]}
			onPress={this.select}
		/>
	}
}

 

2.Header.js

/**
 * 头部组件
 * 引用组件 矢量图标 npm install react-native-vector-icons@3.x --save
 * 原生的组件需要link  react-native link
 */
import React, { Component } from 'react';
import {
	AppState,
	StyleSheet,
	View,
	Text,
	TouchableOpacity
} from 'react-native';

// 引入矢量图标组件
import Icon from 'react-native-vector-icons/FontAwesome';

const styles = StyleSheet.create({
	root: {
		flexDirection: 'row',
		height: 44,
		backgroundColor: '#F5F5F5',
		justifyContent: 'space-between',
		paddingHorizontal: 20,
		alignItems: 'center',
	},
	text: {
		textAlign: 'center',
		fontSize: 18,
	},
	back: {
		fontSize: 20,
		color: '#900',
	},
	right: {
		fontSize: 20,
		color: 'transparent',
	}
});

export default class Header extends Component {
	goBack = () => {
		// 通过解钩 获取传递的navigator
		const { navigator } = this.props;
		navigator.pop();
	};
	render() {
		return (
			<View style={styles.root}>
				<TouchableOpacity onPress={this.goBack}>
					{/*引入Icon组件*/}
					<Icon name="rocket" style={styles.back} />
				</TouchableOpacity>
				<Text style={styles.text}>购物车</Text>
				<TouchableOpacity>
					{/*引入Icon组件*/}
					<Icon name="rocket" style={styles.right} />
				</TouchableOpacity>
			</View>
		);
	}
}

 

3.ItemList.js

/**
 * 列表组件
 */
import React, { Component } from 'react';
import {
	StyleSheet,
	ScrollView
} from 'react-native';

// 引入Item组件
import Item from './Item';

const styles = StyleSheet.create({
	root: {
		flex: 1,
	}
});

// 引入购物车数据
import cartData from '../logics/CartData';

export default class ItemList extends Component {
	render() {
		// 取出父组件传递的参数
		const { cartData } = this.props;

		// 动态创建组件
		return (
			<ScrollView style={styles.root}>
				{
					cartData.map((data,index) => {
						return <Item key={data.id} index={index} data={data} cartData={cartData} />
					})
				}
			</ScrollView>
		);
	}
}

 

4.Item.js

/**
 * 列表子组件
 */
import React, { Component } from 'react';
import {
	StyleSheet,
	View,
	Image,
	TouchableOpacity,
	Text
} from 'react-native';

// 引入observer
import { observer } from 'mobx-react/native';

// 引入Circle组件
import Circle from './Circle';

const styles = StyleSheet.create({
	root: {
		flex: 1,
		flexDirection: 'row',
		justifyContent: 'space-between',
		alignItems: 'center',
		padding: 10,
		height: 100,
	},
	img: {
		width: 90,
		height: 90,
	},
	content: {
		//
	},
	price: {
		//
	},
	name: {
		fontSize: 16,
	},
	priceAndControls: {
		flexDirection: 'row',
		justifyContent: 'space-between',
		alignItems: 'center',
	},
	button: {
		padding: 10,
		justifyContent: 'center',
		borderWidth: StyleSheet.hairlineWidth,
		borderColor: '#000',                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
	},
	buttonText: {
		//
	}
});

// 监听observer
@observer
export default class Item extends Component {
	check = (checked) => {
		const { index, cartData } = this.props;
		cartData.check(checked, index);
	};
	minus = () => {
		const { index, data: { count }, cartData } = this.props;
		// 安全检查
		if(count > 1){
			cartData.minus(index);
		}
	};
	plus = () => {
		const { index, data: { count }, cartData } = this.props;
		cartData.plus(index);
	};
	render() {
		// 取出父组件传递的值 props上的数据只可读不可写(不可更改)
		const { index, data: {id,name,count,img,checked} } = this.props;

		return (
			<View style={styles.root}>
				{/*勾选框*/}
				<Circle onPress={this.check} />
				{/*图片*/}
				<Image style={styles.img} source={{uri: img}} />
				{/*描述*/}
				<View style={styles.content}>
					<Text style={styles.name}>{name}</Text>
					<View style={styles.priceAndControls}>
						<Text style={styles.price}>¥{price.toFixed(2)}</Text>
						<TouchableOpacity
							style={styles.button}
							onPress={this.minus}
						>
							<Text style={styles.buttonText}>-</Text>
						</TouchableOpacity>
						<Text>{count}</Text>
						<TouchableOpacity
							style={styles.button}
							onPress={this.plus}
						>
							<Text style={styles.buttonText}>+</Text>
						</TouchableOpacity>
					</View>
				</View>
			</View>
		);
	}
}

 

5.Footer.js

/**
 * 底部组件
 */
import React, { Component } from 'react';
import {
	AppState,
	StyleSheet,
	View,
	Text,
	TouchableOpacity
} from 'react-native';

// 引入矢量图标组件
import Icon from 'react-native-vector-icons/FontAwesome';

const styles = StyleSheet.create({
	root: {
		position: 'absolute',
		bottom: 0,
		left: 0,  // 设置left、right为0,可实现width:100%的效果
		right: 0,
		justifyContent: 'center',
		flexDirection: 'row',
		height: 44,
		backgroundColor: '#F5F5F5',
		justifyContent: 'space-between',
		borderTopWidth: StyleSheet.hairlineWidth, // 解决1px问题,专门用来设置边界值
		alignItems: 'center', // 元素居中
	},
	selectWrapper: {
		flexDirection: 'row', // 设置主轴为横向
		alignItems: 'center',
		marginLeft: 20,
	},
	checked: {
		backgroundColor: '#f23030',
	},
	selectText: {
		marginLeft: 5,
	},
	checkout: {
		backgroundColor: '#f23030',
		paddingHorizontal: 20,
		height: 50,
		justifyContent: 'center',
	},
	checkoutText: {
		fontSize: 18,
		color: '#fff',
	}
});

// 引入observer组件
import { observer } from 'mobx-react/native';

// 引入勾选框组件 Circle
import Circle from '../components/Circle';

@observer
export default class Footer extends Component {
	// 构造器  状态
	// constructor(props) {
	// 	super(props);
	// 	this.state = {
	// 		//
	// 	}
	// }
	goBack = () => {
		// 通过解钩 获取传递的navigator
		const { navigator } = this.props;
		navigator.pop();
	};
	selectAll = (checked) => {
		// 获取子组件返回值
		alert(checked);
	};
	render() {
		const { cartData } = this.props;
		return (
			<View style={styles.root}>
				<View style={styles.selectWrapper}>
					<Circle onPress={this.selectAll} />
					<Text style={styles.selectText}>全选</Text>
				</View>
				<Text>总计:¥{cartData.sum.get()}</Text>
				<TouchableOpacity
					// 状态不同显示的样式不同
					style={styles.checkout}
					onPress={this.checkout}
				>
					<Text style={styles.checkoutText}>去结算({cartData.count.get()})</Text>
				</TouchableOpacity>
			</View>
		);
	}
}

 

六、数据

CartData.js

/**
 * 通过observer 将数据变成可变的数据(可读写)
 */
import { observable, computed } from 'mobx';

/**
 * 独立于组件的变量,用于存储组件状态
 */
const cartData = observable([
	{
		id: '928128',
		name: '飞利浦(PHILIPS)电吹风机 HP8230 家用大功率恒温护发冷热风',
		price: 620000,
		count: 1,
		img: 'http://img10.360buyimg.com/n7/g14/M06/04/15/rBEhV1HcwMEIAAAAAACwKUjHr8IAAA6egEjTU4AALBB222.jpg!q70.jpg.webp',
		checked: false,
	},
	{
		id: '3926802',
		name: '和情(LOTUS)缤咖时焦糖饼干250g*2袋装',
		price: 6180000,
		count: 1,
		img: 'http://img10.360buyimg.com/n7/s176x176_jfs/t3715/282/1024231787/79825/c65fba1d/581aeeb3N5802976f.jpg!q70.jpg.webp',
		checked: false
	},
]);

// 封装对数据操作的方法
cartData.minus = (index) => {
	cartData[index].count -= 1;
};

cartData.plus = (index) => {
	cartData[index].count += 1;
};

cartData.check = (checked, index) => {
	cartData[index].checked = checked;
};

// 在现有的数据上计算结束后得到的结果
cartData.count = computed(() => {
	// reduce 类似击鼓传花 层层叠加
	return cartData.reduce((a,b) => {
		if(b.checked){
			return a + b.count;
		}else{
			return a;
		}
		// return a + b.checked && b.count;
	},0);
});

cartData.sum = computed(() => {
	// reduce 类似击鼓传花 层层叠加
	return cartData.reduce((a,b) => {
		if(b.checked){
			return a + b.count * b.price;
		}else{
			return a;
		}
		// return a + b.checked && (b.price * b.count);
	},0);
});

export default cartData;

.

posted @ 2017-07-28 19:25  每天都要进步一点点  阅读(802)  评论(0编辑  收藏  举报