欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-09-08 11:55:06
在工作中,购物车场景非常常见。本文实现基于react-native和mobx实现两种购物车例子。 其中,后期会加入动画等其他。本期先实现基础功能。 二:基于stat...

在工作中,购物车场景非常常见。本文实现基于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);

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

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