天天看點

一次性比較目前前端最流行的狀态管理,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有沒有變化.

原文釋出時間:05/12

原文作者:前端大白 

本文來源

開源中國

如需轉載請緊急聯系作者

繼續閱讀