react-native mobx實現購物車demo

import React,{Component} from 'react';
import { View, Text, Image, FlatList,TextInput, TouchableOpacity} from 'react-native';
import {observer,inject } from 'mobx-react'
import {toJS} from 'mobx'

/***
 * toJS  處理mobx返回的數據 toJS(data) = {};
 * @inject 注入監聽的數據 這裏爲 carStore
 * @observer 監聽
 * 
 * created by wangweiruning on 2019-9-25
 * 實現簡單的購物車邏輯
 * ***/ 
@inject('carStore')
@observer
export default class My extends Component{
    constructor(props){
        super(props)
        this.cardata = this.props.carStore;
    }
    
    separatorView = () => {
        return (
            <View style={{ height: 10, backgroundColor: '#e9e9e9' }} />
        )
    };

    renderItem = (item,index) => {
        return (
            <ShoppingItemComponent
                itemData={item}
                // carStore={this.props.carStore}
            />
        )
    };

    keyExtractor = (item) => item.name;

    allSelect = () => {//全部選中,將總的money清空,重新計算
        let carAction = this.cardata;
        if(!this.cardata.selectAll){
          carAction.select_all();  
        }else{
           carAction.select_none(); 
        }  
    };
    
    render(){
        return (
            <View style={{flex:1}}>
                    <Text style={{padding:10,backgroundColor:'red',color:"#FFFFFF"}}>購物車數據</Text>
                    <View style={{ flex: 1, width: "100%", height: '100%' }}>
                        <FlatList data={this.cardata.carData}
                            ItemSeparatorComponent={this.separatorView}
                            renderItem={({ item,index}) => this.renderItem(item,index)}
                            keyExtractor={this.keyExtractor}
                            />
                    <View style={{ flex: 1, flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center',height:50 }}>
                        <View style={{ flex: 1, flexDirection: 'row', alignItems: 'center',width:'20%'}}>
                            <TouchableOpacity style={{ flexDirection: 'row', justifyContent: "flex-end", alignItems: 'center' }} onPress={this.allSelect}>
                               
                            {this.cardata.selectAll?
                                <Image source={require('./src/image/select.png')} style={{width:30,height:30}}/>:
                                <Image source={ require('./src/image/unselect.png')} style={{width:30,height:30}}/>
                            }
                                <Text style={{ marginLeft: 3 }}>全選</Text>
                            </TouchableOpacity>
                            <Text style={{ color: "red" }}>
                                ¥{this.cardata.add_allMoney}
                            </Text>
                        </View>
                        <TouchableOpacity style={{ backgroundColor: "#345678", justifyContent: 'center', alignItems: 'center',width:'70%',paddingVertical:15}}>
                            <Text style={{ color: "#FFFFFF" }}>去結算</Text>
                        </TouchableOpacity>
                    </View>
                </View>
        </View>
        );
    }
}


/**
 * 商品列表展示item
 * @param itemData 元素
 * 
 * **/
@inject('carStore')
@observer
class ShoppingItemComponent extends Component {
   
    constructor(props) {
        super(props);
        this.carStore = this.props.carStore;
    };
    //單個元素選中
    itemSelect = (item) => {
       let carACtion = this.carStore;
       carACtion.select_one(item.shoppingId);
    };
    //單個元素增加
    itemIncrease = (item) => {
        let carACtion = this.carStore;
       carACtion.add_num(item.shoppingId);
    };
    //單個元素減少
    itemReduce = (item) => {
        let carACtion = this.carStore;
        carACtion.cut_num(item.shoppingId);
       
    };
    //刪除列表某個元素
    delectItem=(item) =>{
        let carACtion = this.carStore;
        carACtion.delete_none(item.shoppingId);
        
    }

    render() {
        //獲取的數據必須在render裏面,否則頁面不會更新
        let { itemData } = this.props;
        let isSel= itemData.selectOne;
        let selNum= itemData.count;
        let money= itemData.money;
        let name=itemData.name;
        let description= itemData.discribe;
        return (
            <View style={{ flex: 1, flexDirection: 'row', justifyContent: "space-evenly", alignItems: 'center',width:'100%' }}>
                <TouchableOpacity
                    style={{ marginLeft: 15 }}
                    onPress={() => this.itemSelect(itemData)}>
                    {isSel?
                        <Image source={require('./src/image/select.png')} style={{width:30,height:30}}/>:
                        <Image source={ require('./src/image/unselect.png')} style={{width:30,height:30}}/>
                    }
                </TouchableOpacity>
                {/* <Image style={ styles.icon } source={{ uri : img }}/> */}
                <View style={{ flexDirection: 'column',width:'80%',justifyContent:'flex-start',alignItems:'center'}}>
                    <Text numberOfLines={2}>{name}</Text>
                    <Text numberOfLines={1}>{description}</Text>
                    <View style={{flexDirection:'row',justifyContent:'space-evenly',alignItems:'center',width:'60%'}}>
                        < Text >¥{money}</Text>
                        <View style={{flexDirection:'row',width:'100%',justifyContent:'space-evenly'}}>
                            <TouchableOpacity onPress={() => this.itemReduce(itemData)} style={{padding:6,borderWidth:1,borderColor:"#456789",borderStyle:'solid'}}>
                                <Text style={{ color: selNum <= 1 ? 'red' : 'black' }}>-</Text>
                            </TouchableOpacity>
                            <View >
                                <Text >{selNum}</Text>
                            </View>
                            <TouchableOpacity onPress={() => this.itemIncrease(itemData)} style={{padding:6,borderWidth:1,borderColor:"#456789",borderStyle:'solid'}}>
                                <Text>+</Text>
                            </TouchableOpacity>
                        </View>
                        <TouchableOpacity onPress={() => this.delectItem(itemData)}>
                                <Text>刪除</Text>
                            </TouchableOpacity>
                    </View>
                </View>
            </View>
        );
    }
}

 

import {observable,action, computed} from 'mobx'

 class CarStore {
    @observable carData;
    @observable selectAll = true;

    constructor(carData){
        this.carData= [
                {shoppingId:'good_1',name:'第一個商品',count:1,money:123,discribe:'這是第一個產品啊',selectOne:true},
                {shoppingId:'good_2',name:'第二個商品',count:1,money:55,discribe:'這是第二個產品啊',selectOne:true},
                {shoppingId:'good_3',name:'第三個商品',count:1,money:23,discribe:'這是第三個產品啊',selectOne:true},
                {shoppingId:'good_4',name:'第四個商品',count:1,money:42,discribe:'這是第四個產品啊',selectOne:true}
            ]
    }
    
    @action
    //添加購物車數據
    add_DATA=(item)=>{
        this.carData= this.carData.push({...item,selectOne:true});
    }

    @action
    //添加數量
    add_num=(shoppingId)=>{
        let shopdata = this.carData;
        shopdata.map((item,index)=>{
            if(shoppingId==item.shoppingId){
                this.carData[index].count+=1;
            }
        })
    }
    
    @action
    //減少數量
    cut_num=(shoppingId)=>{
        let shopdata = this.carData;
        shopdata.map((item,index)=>{
            if(shoppingId==item.shoppingId){
                if(this.carData[index].count<=1){
                    this.carData[index].count=1;
                }else{
                    this.carData[index].count-=1;
                }
            }
        })
    }


    @action
    //選中某個商品
    select_one=(shoppingId)=>{
        let shopdata = this.carData;
        shopdata.map((item,index)=>{
            if(shoppingId==item.shoppingId){
                this.carData[index].selectOne = !shopdata[index].selectOne ;
            }  
        })
        let tt = this.carData.filter(item=>item.selectOne===false);//獲取未選中的元素
        this.selectAll=tt.length>0?false:true;//如果有數據將selectAll=false 
        
    }

    @action
    //選中所有商品
    select_all(){
        this.selectAll = true;
        let shopdata = this.carData;
        shopdata.map((item,index)=>{
                this.carData[index].selectOne =true;
            })
    }

    @action
    //清除所有選中
    select_none(){
        this.selectAll = false;
        let shopdata = this.carData;
        shopdata.map((item,index)=>{
                this.carData[index].selectOne =false;
            })
    }


    @action
    //從購物車刪除商品
    delete_none(shoppingId){
        let shopdata = this.carData;
        shopdata.map((item,index)=>{
            if(shoppingId==item.shoppingId){
                this.carData.splice(index,1)
            }
            
            })
    }
    @computed
    //計算所有的金額
     get add_allMoney(){
        let shopdata = this.carData;
        let allMoney = 0;
        shopdata.map((item)=>{
            if(item.selectOne){
                allMoney +=item.count*item.money;
            }
        })
        return allMoney;
    }
}


const carStore= new CarStore();

export {carStore}

 


import {carStore} from './carStore'
const store = { carStore };

export default store;

 

 

學習中。。。

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章