摘要: 一次性比较目前前端最流行的状态管理,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有没有变化.
作者:前端大白
来源:
共同学习,写下你的评论
评论加载中...
作者其他优质文章