当前位置: 移动技术网 > IT编程>开发语言>JavaScript > React-Native使用Mobx实现购物车功能

React-Native使用Mobx实现购物车功能

2017年12月12日  | 移动技术网IT编程  | 我要评论

在工作中,购物车场景非常常见。本文实现基于react-native和mobx实现两种购物车例子。

其中,后期会加入动画等其他。本期先实现基础功能。

二:基于state实现购物车

1-:shoppingcarpage.js

export default class shoppingcarpage extends component {
  static navigationoptions = {
    headertitle : '基于state购物车',
  };

  constructor(props) {
    super(props);
    this.state = {
      allselecte : data.isallselect,
      totalmoney : data.totalmoney,
    }

  };

  getmoney = (m) => {
    this.state.totalmoney=this.state.totalmoney+m;
    //this.state.totalmoney += m;
    data.totalmoney = this.state.totalmoney;
    this.setstate({
      totalmoney : this.state.totalmoney
    });

    let i = 0;
    data.datas.map((item) => {
      if (item.isselect != true) {
        i += 1;
      }
    });
    if (i == 0) {
      data.isallselect = true;
      this.setstate({ allselecte : true })
    }
    else {
      data.isallselect = false;
      this.setstate({ allselecte : false })
    }
  };

  renderitem = (item) => {
    return (
      <shoppingitemcomponent
        itemdata={item}
        money={this.getmoney}
      />
    )
  };

  allselect = () => {
    data.totalmoney = 0;
    data.isallselect = !data.isallselect;
    this.state.totalmoney = 0;
    deviceeventemitter.emit('allselect', !this.state.allselecte);
    this.setstate({ allselecte : !this.state.allselecte })
  };

  separatorview = () => {
    return (
      <view style={{ height : 10, backgroundcolor : '#e9e9e9' }}/>
    )
  };

  keyextractor = (item) => item.name;

  render() {
    let { allselecte, totalmoney } = this.state;
    return (
      <view style={styles.container}>
        <flatlist data={data.datas}
             itemseparatorcomponent={this.separatorview}
             renderitem={({ item }) => this.renderitem(item)}
             keyextractor={ this.keyextractor }
        />
        <view style={styles.tool}>
          <view style={{ flex : 1, flexdirection : 'row', alignitems : 'center' }}>
            <touchableopacity style={styles.select} onpress={ this.allselect }>
              <image source={allselecte ? require('./imgs/login_radio_selected.png') : require('./imgs/login_radio_normall.png')}/>
              <text style={{ marginleft : 3 }}>全选</text>
            </touchableopacity>
            <text style={styles.allmoneytext}>
              ¥{this.state.totalmoney}
            </text>
          </view>
          <touchableopacity style={styles.balance}>
            <text style={styles.balancetext}>去结算</text>
          </touchableopacity>
        </view>


      </view>
    );
  }
}

2-:shoppingitemcomponent.js

export default class shoppingitemcomponent extends component {

  static proptypes = {
    itemdata : proptypes.object.isrequired,
    money : proptypes.func,
  };

  static defaultprops = {
    money : () => null,
  };

  componentdidmount() {
    this.subscription = deviceeventemitter.addlistener('allselect', (isselall) => {
      this.props.itemdata.isselect = isselall;
      this.setstate({ issel : isselall });
      if (isselall) {
        this.setmoney(this.state.money * this.state.selnum);
      }

    })
  };

  componentwillunmount() {
    this.subscription && this.subscription.remove();
  };

  constructor(props) {
    super(props);
    this.state = {
      issel : this.props.itemdata.isselect,
      selnum : this.props.itemdata.count,
      money : this.props.itemdata.money,
      name : this.props.itemdata.name,
      description : this.props.itemdata.description,
      img : this.props.itemdata.img,
    }
  };

  itemselect = (item) => {
    this.setstate({issel :!this.state.issel},()=>{
      if (this.state.issel) {
        this.setmoney(this.state.money * this.state.selnum)
      }
      else {
        this.setmoney(-this.state.money * this.state.selnum)
      }
    });
  };

  itemincrease = (i) => {
    i++;
    this.setstate({selnum : i},()=>{
      if (this.state.issel) {
        this.setmoney(this.state.money)
      }else{
        this.setstate({issel :true});
        this.setmoney(this.state.money * this.state.selnum);
      }
      this.props.itemdata.count = i;
    });
  };

  itemreduce = (i) => {
    if (i <= 1) {
      if(this.state.issel){
        this.setstate({issel :!this.state.issel});
        this.setmoney(-this.state.money)
      }
      return;
    }
    i--;
    this.setstate({ selnum : i },()=>{
      if (this.state.issel) {
        this.setmoney(-this.state.money)
      }else{
        this.setstate({issel :true});
        this.setmoney(this.state.money * this.state.selnum);
      }
      this.props.itemdata.count = i;
    });

  };

  setmoney = (money) => {
    if (this.props.money) {
      this.props.money(money);
    }
  };

  render() {
    let { itemdata } = this.props;
    let { issel, selnum, money, name, description, img } = this.state;
    return (
      <view style={ styles.container }>
        <touchableopacity
          style={{ marginleft : 15 }}
          onpress={() => this.itemselect(itemdata)}>
          <image source={issel ?
            require('./imgs/login_radio_selected.png')
            : require('./imgs/login_radio_normall.png')}/>
        </touchableopacity>
        <image style={ styles.icon } source={{ uri : img }}/>
        <view style={ styles.right }>
          <text style={ styles.namestyle } numberoflines={ 2 }>{ name }</text>
          <text style={ styles.descriptionstyle } numberoflines={1}>{ description }</text>
          <view style={ styles.right_bot}>
            < text style={ styles.moneystyle }>¥{ money }</text>
            <view style={ styles.numcontrollstyle }>

              <touchableopacity style={ styles.reducestyle } onpress={() => this.itemreduce(selnum)}>
                <text style={{ color : selnum <= 1 ? 'red' : 'black' } }>-</text>
              </touchableopacity>
              <view style={ styles.numberviewstyle }>
                <text style={ styles.numberstyle }>{ selnum }</text>
              </view>
              <touchableopacity style={ styles.increasestyle } onpress={() => this.itemincrease(selnum)}>
                <text>+</text>
              </touchableopacity>
            </view>
          </view>
        </view>
      </view>
    );
  }
}

三:基于mobx实现购物车

1-:mobxshoppingcarpage.js

@observer
export default class mobxshoppingcarpage extends component {
  static navigationoptions = {
    headertitle : '基于mobx购物车',
  };

  constructor(props) {
    super(props);
    this.data = new mobxstore();
  };

  componentdidmount() {
    this.data.replace(jsondata)
  };

  @action
  allselect = () => {
    deviceeventemitter.emit('allselect', !this.data.itemdata.isallselect);
    this.data.selectall();
  };

  renderitem = (item) => {
    return (
      <mobxshopitemcomponent itemdata={ item } data={ this.data }/>
    )
  };

  separatorview = () => {
    return (
      <view style={{ height : 10, backgroundcolor : '#e9e9e9' }}/>
    )
  };

  keyextractor = (item) => item.name;

  render() {
    return (
      <view style={ styles.container }>
        <flatlist data={ this.data.itemdata.datas }
             itemseparatorcomponent={ this.separatorview }
             renderitem={ ({ item }) => this.renderitem(item) }
             keyextractor={ this.keyextractor }
        />
        <view style={ styles.tool }>
          <view style={{ flex : 1, flexdirection : 'row', alignitems : 'center' }}>
            <touchableopacity style={ styles.select } onpress={ this.allselect }>
              <image source={ this.data.itemdata.isallselect ?
                require('../imgs/login_radio_selected.png')
                : require('../imgs/login_radio_normall.png') }/>
              <text style={{ marginleft : 3 }}>全选</text>
            </touchableopacity>
            <text style={ styles.allmoneytext }>
              ¥{ this.data.itemdata.totalmoney }
            </text>
          </view>
          <touchableopacity style={ styles.balance } onpress={ this.allselect }>
            <text style={ styles.balancetext }>去结算</text>
          </touchableopacity>
        </view>
      </view>
    );
  }
}

2-:mobxshopitemcomponent.js

@observer
export default class mobxshopitemcomponent extends component {

  static proptypes = {
    itemdata : proptypes.object.isrequired,
    data : proptypes.object.isrequired,
  };

  constructor(props) {
    super(props);
    this.itemdata = this.props.itemdata;
  }

  componentdidmount() {
    this.subscription = deviceeventemitter.addlistener('allselect', (isselall) => {
      this.itemdata.isselect = isselall;
    })
  };

  componentwillunmount() {
    this.subscription && this.subscription.remove();
  };

  @action
  selectpress = () => {
    this.itemdata.isselect = !this.itemdata.isselect;
    let money = this.itemdata.money * this.itemdata.count;
    if (this.itemdata.isselect) {
      this.props.data.increase(money);
    }
    else {
      this.props.data.reduce(money)
    }
    this.props.data.itempress();
  };

  @action
  increase = () => {
    this.itemdata.count += 1;
    if (this.itemdata.isselect) {
      this.props.data.increase(this.itemdata.money);
    }else{
      this.itemdata.isselect = !this.itemdata.isselect;
      this.props.data.increase(this.itemdata.money * this.itemdata.count);
    }

  };

  @action
  reduce = () => {
    if (this.itemdata.count <= 1) {
      if(this.itemdata.isselect){
        this.itemdata.isselect = !this.itemdata.isselect;
        this.props.data.reduce(this.itemdata.money);
      }
      return;
    }
    this.itemdata.count -= 1;
    if (this.itemdata.isselect) {
      this.props.data.reduce(this.itemdata.money);
    }
  };

  render() {
    return (
      <view style={ styles.container }>
        <touchableopacity
          style={{ marginleft : 15 }}
          onpress={ this.selectpress }>
          <image source={ this.itemdata.isselect ?
            require('../imgs/login_radio_selected.png')
            : require('../imgs/login_radio_normall.png') }/>
        </touchableopacity>
        <image style={ styles.icon } source={{ uri : 'https://img10.360buyimg.com/n7/jfs/t4063/153/323373745/444727/87c24f22/58b11156n9be178c2.jpg' }}/>
        <view style={ styles.right }>
          <text style={ styles.namestyle } numberoflines={ 2 }>{ this.itemdata.name }</text>
          <text style={ styles.descriptionstyle } numberoflines={1}> { this.itemdata.description }</text>
          <view style={ styles.right_bot}>
            < text style={ styles.moneystyle }>¥{ this.itemdata.money }</text>
            <view style={ styles.numcontrollstyle }>
              <touchableopacity style={ styles.reducestyle } onpress={ this.reduce }>
                <text style={{ color : this.itemdata.count <= 1 ? 'red' : 'black' } }>-</text>
              </touchableopacity>
              <view style={ styles.numberviewstyle }>
                <text style={ styles.numberstyle }>{ this.itemdata.count }</text>
              </view>
              <touchableopacity style={ styles.increasestyle } onpress={ this.increase }>
                <text>+</text>
              </touchableopacity>
            </view>
          </view>
        </view>
      </view>
    );
  }
};

3-:mobxstore.js

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

export default class mobxstore {
  @observable
  itemdata = {}

  //设置数据
  replace = (data) => {
    this.itemdata = data;
  }

  //按下的反选
  itempress = () => {
    let i = 0;
    this.itemdata.datas.map((item) => {
      if (item.isselect != true) {
        i += 1;
      }
    });
    if (i == 0) {
      this.itemdata.isallselect = true;
    }
    else {
      this.itemdata.isallselect = false;
    }
  }

  //加
  increase = (money) => {
    this.itemdata.totalmoney += money;
  }

  //减
  reduce = (money) => {
    this.itemdata.totalmoney -= money;
  }

  //全选
  selectall = () => {
    this.itemdata.isallselect = !this.itemdata.isallselect;
    this.itemdata.totalmoney = 0;
    if (this.itemdata.isallselect) {
      for (let i = 0;
        i < this.itemdata.datas.length;
        i++) {
        this.itemdata.totalmoney += this.itemdata.datas[ i ].money * this.itemdata.datas[ i ].count;
      }
    }
  }
}

四:

1-:代码github地址:https://github.com/erhutime/react-navigation-all/tree/master/all/jscode/shoppingcar/src

2-:下载完成后,修改index.ios.js:入口文件如下:

运行效果如下:

import app from './jscode/shoppingcar/src/app'
appregistry.registercomponent('all', () => app);

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持移动技术网。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网