1
redux和mobx都是react比较热门的状态管理工具,从个人操作来看,我觉得mobx相对更简单,单向数据流,业务逻辑比较清晰,现在来简单介绍一下.
MobX 的理念是通过观察者模式对数据做出追踪处理,在对可观察属性的作出变更或者引用的时候,触发其依赖的监听函数,在React中即是在 @observer 中对组件进行数据更新,监听,并渲染到视图层面.
简单原理来说:先通过 @observable设置可观察数据 (state),然后通过@observer这个观察者去订阅组件内的可观察数据,当通过@action对可观察数据修改的时候,@observer会马上对组件进行数据更新并渲染到视图层面.
@observable  //可观察的数据 observable 的属性值在其变化的时候mobx会自动追踪并作出响应

@observer   //观察者  订阅数据

@action  //动作(Action) 执行修改State(observable) 的函数  
可观察的属性值, 在他们改变的时候则会触发观察监听的函数

@computed  // 计算属性 get和set可以用来控制computed的行为:  
//get:基于state值,通过一些计算得到的新值并返回给调用者。  
//set:get的相反运算,参数为一个值,由该值进行get函数中的反运算,得到对应的state值并赋予state。

cnpm i  mobx   ~~~~mobx-react -S  //安装mobx

项目中新建一个mobx文件夹,然后新建shopcar.js

//引入mobx的主文件  并进行相关验证
import { observable, action, computed, } from "mobx";

import { axios } from "&";  //数据请求文件,我之前封装在项目utils里面了, &是别名设置

class Shopcar {
    //显示购物车列表
    @observable carList = []   //定义购物车的列表数据

    //action执行动作  得到商品列表
    @action getCarList = async (url) => {
        const res = await axios.get(url);
        this.carList = res.data.result;
    }
     //删除选中
     @action delSelect=()=>{
        axios.post("/react/delSelect").then(res=>{
          this.carList=this.carList.filter(item=>!item.checked);
            //将没有选中的商品过滤出来
        })
    }
    //单选
    @action  changeOneChecked=(checked,goodsid)=>{
        axios.post("/react/changeChecked",{
            goodsid,
            checked
        }).then(res=>{
            this.carList=this.carList.map((item)=>{
                if(item.goodsid==goodsid){
                    item.checked=checked
                }
                return item;   //每一个商品
            })
        })
    }
    //全选
    @action changeQuan=(checked)=>{
        axios.post("/react/changeChecked",{
            checked
        }).then(res=>{
            this.quan=checked
        })
    }
    //选中单个数量  包含加和减    利用flag的正负
    @action changeOneCount=(goodsid,flag)=>{
            axios.post("/react/changeCount",{
                goodsid,
                flag

            }).then(res=>{
                this.carList=this.carList.map((item)=>{
                    if(item.goodsid==goodsid){
                        item.count+=flag?1:-1;
                    }
                    return item;   //每一个商品
                })
            })
    }
    //通过输入数值直接修改购物车里面的具体数值
    @action changeOneCountNum=(goodsid,count)=>{
        axios.post("/react/changeCount",{
            goodsid,
            count
        }).then(res=>{
            this.carList=this.carList.map((item)=>{
                if(item.goodsid==goodsid){
                    item.count=count
                }
                return item;        //具体修改多少就数据库有插入多少
            })
        })
    }
    //得到总数
    @computed get carTotal() {
        var carTotal = 0;   //设置默认值
        this.carList.forEach((item) => {
            carTotal += item.count
        })
        return carTotal;
    }
    //得到购物车选中的数量数量
    @computed get carNum() {
        var carNum = 0;
        this.carList.forEach((item) => {
            if (item.checked) {
                carNum += item.count
            }

        })
        return carNum;
    }
    //得到选中的商品去订单页面
    @computed  get checkedGood(){
        var checkedGood=[]
        this.carList.forEach((item) => {
            if (item.checked) {
                // checkedGood += item
                checkedGood.push(item);
            }

        });
        return checkedGood
    }
    //得到总价  等于数量乘以价格
    @computed get total() {
        var total = 0;
        this.carList.forEach((item) => {
            if (item.checked) {
                total += item.count * item.good.jiage
            }
        })
        return total;
    }
    //全选事件
    @computed get quan(){
        var quan = true;
        this.carList.forEach(item=>{
            if(!item.checked){
                quan = false;
            }
        })
        return quan;
    }
    //监听并改变全选事件
    set quan(newVal) {
        this.carList = this.carList.map((item) => {
            item.checked = newVal;
            return item;
        })
    }
}

//底下以构造函数的方式暴露
export default new Shopcar();

view视图文件下渲染实现购物车shopcar/index.js

import shopcar from "~/mobx/shopcar"
import { observer } from "mobx-react";
import { success } from "&/axios";  //封装的axios拦截器

@observer
class Shopcar extends Component {
    componentDidMount() {
       //运用mobx得到购物车列表信息
      shopcar.getCarList("/react/shopcar/showshoppingcar")
    }
    //自定义函数
    //单选
    checkOne = e => {
        console.log(e);   //可以拿到goodsid 和checked
        shopcar.changeOneChecked(e.target.checked, e.target.goodsid)
    }
    //全选
    checkAll = e => {
        console.log(e);
        console.log(e.target.checked);
        shopcar.changeQuan(e.target.checked);
    }
    //加数量
    add = (goodsid, count) => {
        shopcar.changeOneCount(goodsid, true)
    }
    //减数量
    reduce = (goodsid, count) => {
        shopcar.changeOneCount(goodsid, false)
    }
    //改具体的数值  使用v避免与e同名
    changeCount = (goodsid, v) => {
        console.log(v.target.value);
        if (v.target.value > 1) {
            //字符串要转数字
            shopcar.changeOneCountNum(goodsid, v.target.value * 1);
        }
    }
    //删除选中
    delSelect = () => {
        shopcar.delSelect();
    }
    render() {
        const {
            carList,
            carNum,
            total,
            quan,
            checked,
            checkedGood
        } = shopcar 
    }
}
export default Shopcar

ok了.


Banshee
124 声望4 粉丝

To die is to die, to live is to suffer