一次性比较目前前端最流行的状态管理,mobx,vuex,redux-saga使用方式用方式

首先还是要说明一下:

三者都是状态管理库,这三个如果对其中一个深有体会的话,其它两个要再入门就不再难了,我就是在开始的时候只会redux-saga,由于目前工作中使用了mobx,去官网看了一下,也是基本差不多的,vuex也是一样!

  • redux-saga使用方式:
import request from '../../utils/request';
import PublicService from '../../services/PublicService'
import PointManageService  from '../../services/stationRule/pointManageService'

export default {
  namespace: 'pointManage',
  state: {

    selectedRows:[], // 选中行
    deviceId:'', // 设备id 用来获取左侧数据参数
    size: 10,
    page: 1,
    total: 20,
    initData:{},
    loading: false,
    dataSource:[],
    isVisible:false,
    treeData:[],
  },
  effects: {
    //获取右侧数据
    *getRightData({payload},{put,call,select}){
      let deviceId = yield select(state => state.pointManage.deviceId);
      let res = yield call(PointManageService.getRightData,deviceId);
    },

    *submit({payload},{put,call,select,}){
      yield put({type:'saveInfo',payload:{isVisible:false}})
    },

    * saveInfo({payload}, {put, call, take, select}) {
      let obj = PublicService.deepClone(payload);
      yield put({type: 'save', payload: {...obj}});
    }
  },
  reducers: {
    save(state, {payload}) {
      console.log(payload, 'reduce');
      return {...state, ...payload};
    },
  },
};

redux中最主要的几个api:call,put,select,take.

call:是用来调用外部的函数,

put:调用这个命名空间下的函数

select:选择所有命名空间下的state里的数据,可以通过打印select函数里的参数state查看.

take:我写过一篇文章专门介绍这个api.

redux中的effects改变初始的state(相当于action),再通过唯一能改变state的reducers来改变state,页面刷新.

在页面中的使用方式:

handleOk() {
  this.props.dispatch({type:'pointManage/submit'})
};

我用的是dva脚手架来写的,使用起来是不是很方便?

  • mobx使用方式

目前公司用的mobx,当然了在进这家公司之前我是没有听过mobx的,自己也是花了1个星期自学学会的,上代码:

import Service from './Service';
import {observable, computed, autorun} from 'mobx';

export default new class GStore {

  constructor() {
    // 获取页面列表数据 autorun 为mobx提供方法,当函数里面变量发生改变会自动调用此函数
    autorun(async () => {
      this.geekStyleList.isLoading = true;
      let params = {
        currentPage: this.pageInfo.currentPage,
        pageSize: this.pageInfo.pageSize,
        sortWay: this.query.sortWay,
        skillId: this.query.skillId,
        keyWord: this.query.keyWord
      };
      try {
        let res = await Service.getGList(params);
        let {data} = res;
        if (res.code === '0' && data && data.gList) {
          this.pageInfo.total = data.pageCount;
          this.gStyleList.list = data.gList;
          this.gStyleList.isLoading = false
        }
      }
      catch (e) {
        console.log(e)
      }
    })
  }

  service = Service;
 


  // 列表数据,写成一个对象方便以后维护
  @observable gStyleList = {
    isLoading: true,
    list: []
  };

  // 以下为搜索条件
  @observable query = {
    sortWay: '',
    skillId: '全部',
    keyWord: ''
  };
  // page相关数据
  @observable pageInfo = {
    currentPage: 1,
    pageSize: 12,
    total: 110
  };
  // 当跳转页面时候 需要执行的函数
  pageChange = (page) => {
    this.pageInfo.currentPage = page
  };

  // 搜索条件改变时候需要调用的函数
  onQueryChange = (key, value) => {
    this.query[key] = value;
    this.pageInfo.currentPage = 1;
  };
}

这里用到了mobx的api:autorun,observable,computed(这里没有用到,不过这个api也是非常好用的),具体的使用介绍,可以去官网参考一下.使用感觉mobx更加智能化,在这个store初始化的时候,会自动调用一次autorun里的函数,这个时候mobx会根据这个函数里依赖的observable创建一个依赖图谱,当这个依赖图谱里的observable发生改变的时候,会再一次自动调用这个函数,我想说真的是6666,在网上有看到redux与mobx的性能比较,差不多的性能.

在页面中的使用方式:

直接import后,然后调用store里的方法就可以了,so easy!

  • vuex使用方式

vuex是我最近学习微信小程序所学的,微信小程序原生的写法有些让人蛋疼,后来出了一个wepy,类vue的写法,后来美团出了一个mpvue,直接就是上vue的写法,当然了还是有很多vue的写法在mpvue编译到原生小程序的时候是不适用的,在我博客里有介绍相关的内容,不清楚后期mpvue会不会做到完全兼容.

下面上代码:

import vue from 'vue';
import Vuex from 'vuex';
import service from '../service/service'
import PubliceServeice from '../service/PublicService'

vue.use(Vuex);

const myStore = new Vuex.Store({
  state: {
    categoryList: [], // 菜谱目录list
    menuList: [], // 菜谱list
    menu: [], // 单个菜谱
    collectedArray: [], // 已经被收藏的列表,从localStorage中获取的
    current: 1, // 获取第一页的菜谱数据
    categoryId: '', // 保存点了首页哪个目录的id
    isCollected: false, // 是否被收藏
    isLoading: true
  },

  mutations: {
    //--以下为首页调用方法--//

    // 获取首页类名数据
    getCategory: async (state) => {
      state.isLoading = true;
      await service.getCategory()
        .then(res => {
          state.categoryList = res.data.result;
          state.categoryList.forEach(item => {
            item.isShow = false;
            state.isLoading = false
          })
        });
    },
    // 获取用户收藏列表数据
    getCollectedMenu(state) {
      state.collectedArray = PubliceServeice.getStoreage('collected') || [];
    },
    // 点击展开类名详细数据
    accordionHandle(state, parentId) {
      let lists = state.categoryList;
      let item = lists.find(item => item.parentId === parentId);
      let showBoolean = item.isShow;
      lists.forEach(item => {
        item.isShow = false;
      });
      item.isShow = !showBoolean;
      state.categoryList = JSON.parse(JSON.stringify(lists));
    },
    // 点击搜索调用函数
    getSearchResult(state, menu) {
      service.getMenu({menu})
        .then(res => {
          state.menuList = res.data.result.data;
        })
    },
    // 获取唯一的菜谱
    getUniqueMenu(state, id) {
      let array = new Array(state.collectedArray.find(item => item.id === id)) || [];
      state.isCollected = array[0] ? true : false; // 根据localstorage里的数据来判断是否被收藏了
      state.menu = state.menuList.filter(item => item.id === id);
    },
    // 点击收藏时触发的函数
    collectHandle(state) {
      let array = state.collectedArray;
      let newArray = [];
      if (state.isCollected) {
        newArray = array.filter(item => item.id !== state.menu[0].id);
        PubliceServeice.setStoreage('collected', newArray);
        PubliceServeice.showToast('取消成功', 'success');
        this.commit('getCollectedMenu')
      } else {
        array.push(state.menu[0]);
        PubliceServeice.setStoreage('collected', state.collectedArray);
        PubliceServeice.showToast('收藏成功', 'success')
      }
      state.isCollected = !state.isCollected;
    },
    getCollect(state, id) {
      let array0 = new Array(state.collectedArray.find(item => item.id === id)) || [];
      state.isCollected = array0[0] ? true : false; // 根据localstorage里的数据来判断是否被收藏了

      let array = state.collectedArray; // 收藏列表菜谱
      let array2 = state.menuList; // 首页点击进去菜谱列表
      let array3 = [...array, ...array2];
      state.menu = [array3.find(item => item.id === id)];
    },
    async categoryHandle(state, id, first) {
      if (id !== undefined) {
        state.categoryId = id;
      }
      state.isLoading = true;
      await service.getByCategory({categoryId: state.categoryId, current: state.current})
        .then(res => {
          state.menuList = [...state.menuList, ...res.data.result.data];
          state.current++;
          state.isLoading = false
        })
    },
    save(state, payload) {
      let obj = {...state, ...payload};
      state = JSON.parse(JSON.stringify(obj))
    }
  },

  actions: {}

});


export default myStore

这个是我最写的微信小程序的代码,关于菜谱大全,预计会在下周公开在我的博客里,敬请关注,希望能得到各位的star(目前已经成功上线了).

在页面中的使用方法:

<script>
  import store from '../../models/store';
  import config from '../../config';
  import myPanel from '../../components/myPanel'
  export default {

    data(){
      return{
      }
    },
    methods:{

    },
    components:{
      myPanel
    },
    computed:{
      img(){
        return store.state.menu[0].albums[0]
      }
    },
    mounted(){
      wx.setNavigationBarTitle({  title: store.state.menu[0].title})
    }


  }
</script>

引入,然后在在computed的方法中实时监听img有没有变化.

关于vuex,感觉写的不是很好,用这个的时候基本属性赶鸭子上架,能实现效果就可以,希望看到的大神能给一份大神的代码供我参考

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏FreeBuf

Kali Linux下社工密码字典生成工具Cupp和Cewl教程

Cupp是一款用Python语言写成的可交互性的字典生成脚本。尤其适合社会工程学,当你收集到目标的具体信息后,你就可以通过这个工具来智能化生成关于目标的字典。当...

4166
来自专栏MasiMaro 的技术博文

WinSock 完成端口模型

之前写了关于Winsock的重叠IO模型,按理来说重叠IO模型与之前的模型相比,它的socket即是非阻塞的,也是异步的,它基本上性能非常高,但是它主要的缺点在...

1022
来自专栏程序员的SOD蜜

单数据库,多数据库,单实例,多实例不同情况下的数据访问效率测试

最近公司的项目准备优化一下系统的性能,希望在数据库方面看有没有提升的空间,目前压力测试发现数据库服务器压力还不够大,Web服务器压力也不是很大的情况下,前台页面...

23810
来自专栏沈唁志

USpider~一只超级污的司机蜘蛛

之前就看到了狂放小朋友的PHP版本的污言爬虫,然后我就征求了一下小朋友的意见,就改成了Python版本的爬虫,也算是当做练手了

1192
来自专栏从零开始学自动化测试

python接口自动化21-规范的API接口文档示例

前言 接口文档到底长啥样?做接口测试最大的障碍在于没有接口文档,很多公司不注重接口文档的编写,导致测试小伙伴没见过接口文档。 运气好一点的测试小伙伴可能厚着脸皮...

1.2K8
来自专栏Spark生态圈

spark任务之Task失败监控

在spark程序中,task有失败重试机制(根据 spark.task.maxFailures 配置,默认是4次),当task执行失败时,并不会直接导致整个应用...

3633
来自专栏日常学python

如何爬取asp动态网页?搞定可恶的动态参数,这一文告诉你!

这个asp网站是我的学校的电费查询系统,需要学校的内网才能查询,所以这文说下思路和我遇到的一些坑。我搞这个网站主要是为了方便查电费而已,其实也方便不了多少。而且...

2083
来自专栏Java3y

AJAX入门这一篇就够了

什么是Ajax Ajax(Asynchronous JavaScript and XML) 异步JavaScript和XML Ajax实际上是下面这几种技术的融...

9758
来自专栏移动开发之家

Android全面插件化RePlugin流程与源码解析

RePlugin,360开源的全面插件化框架,按照官网说的,其目的是“尽可能多的让模块变成插件”,并在很稳定的前提下,尽可能像开发普通App那样灵活。那么下面就...

1161
来自专栏Spark学习技巧

Kafka源码系列之副本同步机制及isr列表更新

一,基本思路 <Kafka源码系列之Consumer高级API性能分析>读过这篇文章的同学必然会对本篇文件较为熟悉,因为该篇讲的副本同步,实际上也是基于Simp...

6046

扫码关注云+社区