zoukankan      html  css  js  c++  java
  • react+flux 仿淘宝购物车

    react+flux 仿淘宝购物车


        之前用react写了个表格的单表组件,然后在网上又看到别人家写的一些表格组件,瞬间感觉自己弄的东西好low。不过在写表格组件的时候遇到过一个关于react单向数据流传递的问题,通过一层一层子组件传递完成。而在网上却看到说可以用flux这个的store来方便实现。所以今天特地来实际操作一把,浅鄙见识大家多多指教。

    目录结构

    这是flux官方推荐的目录结构,其中组件放在components当中,stores中实现数据结构的存储,actions实现控制器的功能。这样就可以实现一个前端的mvc模型。因为react在前段将view层做得很好,不能单靠它实现mvc,所以facebook就又来了个flux两个组合实现一个前端mvc模型。其中app是启动应用。

    具体代码

    说了这么多,还是赶紧上代码。

    先看看stores中存储的的东西。

    /*
     *购物车商品模块
     */
    var AppDispatcher = require('../dispatcher/AppDispatcher');
    var EventEmitter = require('events').EventEmitter;
    var Constants = require('../constants/Constants');
    var assign = require('object-assign');
    
    
    var CHANGE_EVENT = 'change';
    
    var _moneyCateray = {};
    var _storage = localStorage;
    _moneyCateray = JSON.parse(_storage.getItem('_moneyCateray'));
    /**
     *添加购物车商品
     */
    function countsPur(purchase){
      /**
       *初始化检测
       */
      if(isEmpty()){
        _moneyCateray[purchase.id] = {
          price:0,
          count:1,
          detail:purchase
        };
        _moneyCateray[purchase.id].price += parseFloat(purchase.price);
        _storage.setItem('_moneyCateray',JSON.stringify(_moneyCateray));
        return;
      }
      /**
       *查看是否有同类单品
       */
      var flag = 0;
      for(var i in _moneyCateray){
        if(i == purchase.id){
          flag = 1;
          break;
        }
      }
      /**
       *将单品价格分类叠加
       */
      if(flag){
        _moneyCateray[purchase.id].price += parseFloat(purchase.price);
        _moneyCateray[purchase.id].count += 1;
      }
      else{
        _moneyCateray[purchase.id] = {
          price:0,
          count:1,
          detail:purchase
        };
        _moneyCateray[purchase.id].price += parseFloat(purchase.price);
      }
      _storage.setItem('_moneyCateray',JSON.stringify(_moneyCateray));
    }
    
    /**
     *删除商品
     */
    function deletePur(id){
      delete _moneyCateray[id];
      _storage.setItem('_moneyCateray',JSON.stringify(_moneyCateray));
    }
    
    /**
     *删除一件商品的数量
     */
    function deleteCount(id){
      if(_moneyCateray[id].count!=0){
        _moneyCateray[id].count -= 1;
      }else{
        _moneyCateray[id].count = 0;
      }
      _storage.setItem('_moneyCateray',JSON.stringify(_moneyCateray));
    }
    
    /**
     *检测_moneyCateray是否为空
     */
    function isEmpty(){
      for(var i in _moneyCateray){
        return false;
      }
      return true;
    }
    
    
    var Store = assign({}, EventEmitter.prototype, {
    
      /**
       *获取总价
       */
       getMoney:function(){
        return JSON.parse(_storage.getItem('_moneyCateray'));
      },
    
      /**
       *侦听事件变化
       */
      emitChange: function() {
        this.emit(CHANGE_EVENT);
      },
    
      addChangeListener: function(callback) {
        this.on(CHANGE_EVENT, callback);
      },
    
      removeChangeListener: function(callback) {
        this.removeListener(CHANGE_EVENT, callback);
      }
    });
    
    /**
     *注册事件
     */
    AppDispatcher.register(function(action) {
      var purchase;
    
      switch(action.actionType) {
        case Constants.PURCHASE_ADD:
          purchase = action.purchase;
          if (purchase !== '') {
            countsPur(purchase);
            Store.emitChange();
          }
          break;
        case Constants.PURCHASE_DELETE:
          deletePur(action.id);
          Store.emitChange();
          break;
        case Constants.PURCHASE_SUB:
          deleteCount(action.id);
          Store.emitChange();
          break;
    
        default:
          // no op
      }
    });
    
    module.exports = Store;
    

    其中AppDispatcher是flux推荐的用来注册事件的,我个人感觉是通过这个来实现控制器功能,调用相应的函数功能。
    下面来看看ui组件部分的代码

    上面是把组件分拆出来的,如下图

    将组件分拆,react官网上也这么推荐这样将一个组件尽量分拆出来http://facebook.github.io/react/docs/thinking-in-react.html

    单个商品

    
    var React = require('react');
    //var Actions = require('../actions/Actions');
    
    
    var Per = React.createClass({
    
    	getInitialState: function(){
    		/**
    		 *商品id,价格,详情,图片地址
    		 */
    		return {
    			id:this.props.id,
    			price:this.props.purchase.price,
    			detail:this.props.purchase.detail,
    			url:this.props.purchase.url,
    		}
    	},
    
    	render: function(){
    		var price = this.state.price;
    		return(
    			<div className="per">
                    <img src={this.state.url} />
                    <h3>¥<span>{(parseFloat(price)).toFixed(2)}</span></h3>
                    <div className="title">{this.state.detail}</div>
                    <a href="javascript:void(0)" className="button orange addcart" onClick={this._OnSave}>加入购物车</a>
                </div>
    			);
    	},
    
    	_OnSave: function(){
    		this.props.OnSave(this.state);
    	}
    });
    
    module.exports = Per;
    

    商品列表

    /*
     *购物列表
     */
    
    var React = require('react');
    var Per = require('./Per');
    var Actions = require('../actions/Actions');
    var Store = require('../stores/purchase');
    
    
    var PerList = React.createClass({
    
    	getInitialState: function(){
    		/**
    		 *商品id,价格,详情,图片地址
    		 */
    		return {
    			list:this.props.lists
    		};
    	},
    
    	componentWillUnmount: function(){
    
    	},
    
    	componentDidMount: function() {
    	    Store.addChangeListener(this._onChange);
    	},
    
    	componentWillUnmount: function() {
    	   Store.removeChangeListener(this._onChange);
    	},
    
    	render: function(){
    		var list = [];
    		var purchase = this.state.list;
    		for(var i in purchase){
    			list.push(<Per purchase={purchase[i]} key={i} id={i} OnSave={this._onSave} />);
    		}
    		return(
    			<div className="demo">
    			  {list}
                </div>
    			);
    	},
    
    	_onChange: function() {
    	    //this.setState(getTodoState());
    	},
    
    	_onSave: function(pur){
    		Actions.addPur(pur);
    	}
    });
    
    module.exports = PerList;
    

    购物车

    /*
     *购物车列表
     */
    
    var React = require('react');
    var Store = require('../stores/purchase');
    var Actions = require('../actions/Actions');
    var PurchaseItem = require('./PurchaseItem');
    
    var PurchaseCar = React.createClass({
    
    	getInitialState: function(){
    		return {
    			purchaseCar:Store.getMoney()
    		};
    	},
    
    	componentDidMount: function() {
    	    Store.addChangeListener(this._onChange);
    	},
    
    	componentWillUnmount: function() {
    	   Store.removeChangeListener(this._onChange);
    	},
    
    	render: function(){
    		var car = this.state.purchaseCar;
    		var PuchaseCarList = [];
    		for(var i in car){
    			PuchaseCarList.push(
    				<PurchaseItem 
    				  key={i} 
    				  purchase={car[i]} 
    				  AddItem={this._addItem} 
    				  SubItem={this._subItem}
    				  DeleteItem={this._deleteItem}/>);
    		}
    		return(
    			<div>{PuchaseCarList}</div>
    			);
    	},
    
    	_onChange: function(){
    		this.setState({purchaseCar:Store.getMoney()});
    	},
    
    	_addItem: function(pur){
    		Actions.addPur(pur.detail);
    	},
    
    	_subItem: function(id){
    		Actions.subPur(id);
    	},
    
    	_deleteItem: function(id){
    		Actions.deletePur(id);
    	}
    });
    
    module.exports = PurchaseCar;
    

    通过上面几块代码就实现了一个简单的前端的mvc模型。具体效果如图

  • 相关阅读:
    四则运算————javaweb版
    构建之法阅读笔记02
    十一周学习进度条
    软工概论-课堂练习:添加信息
    梦断代码阅读笔记01
    链接doc命令行的mysql的编码问题
    构建之法阅读笔记01
    第十周学习进度条
    web
    sql初——基础
  • 原文地址:https://www.cnblogs.com/marvinemao/p/5046877.html
Copyright © 2011-2022 走看看