欢迎来到258分享网,纯净的网络源码分享基地!

258资源分享网

全部作品
全部作品
网站源码
微信源码
素材特效
源码插件
视频教程
建站学院
热门搜索: 织梦  农业种植  农业  安全设置  官方
258资源分享 > 建站学院 > 微信开发 > 微信小程序项目重构之Redux状态管理

推荐下载

HTML5响应式自适应网咯设计

2020-05-12   浏览:789

HTML5自适应律师工作室类网

2020-04-04   浏览:654

高端HTML5响应式企业通用网

2020-05-06   浏览:560

html5响应式外贸网站英文版

2020-05-08   浏览:545

HTML5影视传媒文化公司类网

2020-05-12   浏览:543

微信小程序项目重构之Redux状态管理

发布时间:2020-12-22  

1.以往处理状态的一些方式第一种:App上挂globalData 这种方式就是直接写在App里面啦,取值赋值比较方便App.jsApp({globalData: {name: '前端学者',// ...other globalData},// ...other globalData});// 取值 var ...

 

 

 

1.以往处理状态的一些方式

第一种:App上挂globalData 这种方式就是直接写在App里面啦,取值赋值比较方便

App.js

App({
globalData: {
name: '前端学者',
// ...other globalData
},
// ...other globalData
});

// 取值 var name = getApp().globalData.name;
// 赋值
getApp().globalData.name = '改个名字';

第二种:自己定义一个或者多个用于存储数据的libData文件,自己造轮子,爱折腾的就直接撸吧

例如libData.js

module.exports = { name: '前端学者', // ...other globalData } // ...other // 简单使用 var store = require('./path/to/lib/libData.js'); // 取值 var name = store.name; // 赋值 store.name = '改个名字';

第三种:把要使用的数据存在页面data或者直接存在页面上,比较分散而且不利于管理和维护,但是对于超小且需要快速实现的项目也足够了。别笑,我们前端不怕这样写,O(∩_∩)O哈哈~

dataInPage.js Page({ data: { name: '前端学者' }, name: '前端学者' }); // 取值 var name = this.data.name; var name = this.name; // 赋值 this.setData('name', '改个名字'); this.name = '改个名字');

2.对于处理状态数据,有时候可能还会混着使用上面的几种方式,随着项目复杂度提升,状态将难以管理。

所以呢,我们需要借鉴web端现有的一些优秀成熟的方案,今天的主角就是它了,大家都可能很熟悉,欢迎Redux出场!网上各类的资料已经很详细地介绍,不清楚的同学务必了解Redux,这里只详细说明一下怎么在小程序里面使用,和在React中的用法非常相似,因为核心库mina-redux.js(原名wechat-weapp-redux)的作者就是这么改过来的,这个轮子已经非常棒了。下面直接上代码了,代码虽然多,但具有实站参考价值,所以直接贴上来了。

不使用任何构建工具,把微信开发者工具中项目设置的钩子全部打上,大方地使用import和export吧,现在不需要自己写构建了

ES6 转 ES5

上传代码时样式自动补全

代码上传时自动压缩

不校验安全域名、TLS版本以及HTTPS证书

核心还是Redux,和几个好用的相关库,这几个都是从网上精简了拿过来的,没有用到npm等包管理工具

lib文件夹下:

redux.js(核心文件,必选)

redux-logger(core.js, deep-diff.js, defaults.js, diff.js, helpers.js, index.js 这些都是为了打印日志用的,可选)

redux-thunk.js(异步action中间处理,推荐)

mina-redux.js(核心文件,把redux的dispatch和仓库数据同步到页面上,必选)

remote-redux-devtool.js(远端调试使用,可以直观看到数据流向,非常强大,可选)

remotedev-server.js(远程调试服务,可选,方便调试)

regenerator-runtime.js(facebook的异步库,与redux没有任何关系,可选,极力推荐)

先写redux相关的type action reducer

app.redux.js (个人喜好把type action reducer写在一个文件)

/** * 处理小程序生命周期和载入的一些数据 */ import regeneratorRuntime from '../lib/regenerator-runtime'; import util from '../lib/util'; import api from '../lib/api'; import { minaScecne } from '../config/config'; const WX_SYSTEM_INFO = 'WX_SYSTEM_INFO'; const WX_USER_INFO = 'WX_USER_INFO'; const WX_ON_LAUNCH = 'WX_ON_LAUNCH'; const WX_GET_CODE = 'WX_GET_CODE'; const WX_API_PROMISIFY = 'WX_API_PROMISIFY'; const LOGIN_BEGIN = 'LOGIN_BEGIN'; const LOGIN_PENDING = 'LOGIN_PENDING'; const LOGIN_SUCCESS = 'LOGIN_SUCCESS'; const LOGIN_FAIL = 'LOGIN_FAIL'; // 用法1 // 不用中间件,一个action每次只能dispatch一个action export const wxApiPromisify = () => ({ type: WX_API_PROMISIFY, data: util.initWxMethod() }) export const wxSystemInfo = (data) => ({ type: WX_SYSTEM_INFO, data: data }) export const wxUserInfo = (data) => ({ type: WX_USER_INFO, data: data }) export const wxOnLaunch = (data = {}) => { const { scene, query, path } = data; Object.keys(minaScecne).map((item => { if (scene.toString() === item) { data.sceneText = minaScecne[item] } })); return { type: WX_ON_LAUNCH, data: data } } // 用法2 // app上以store.dispatch(actionMethodName)的方式调用,可以组合action export const login = async dispatch => { const wxLoginResult = await wx.async.login(); await dispatch({ type: WX_GET_CODE, data: wxLoginResult }) await dispatch({ type: LOGIN_BEGIN, data: { isFetching: false } }) await dispatch({ type: LOGIN_PENDING, data: { isFetching: true } }) if(wxLoginResult.code){ try { const apiLoginResult = await api.user.login({ code: wxLoginResult.code }); await dispatch({ type: LOGIN_SUCCESS, data: apiLoginResult }) wx.setStorageSync('token', apiLoginResult.data.token) } catch (error) { await dispatch({ type: LOGIN_FAIL, data: error }) } } else { await dispatch({ type: LOGIN_FAIL, data: wxLoginResult.errMsg }) } } // 用法3 // 使用thunk中间件可以对一个action进行细化出多个状态,比如请求,可以做用于处理ui loading // TODO 写个request action helper 封装一下,不用每次写那么多... export const thunkExampleAction = () => ( async dispatch => { const wxLoginResult = await wx.async.login(); await dispatch({ type: WX_GET_CODE, data: wxLoginResult }) await dispatch({ type: LOGIN_BEGIN, data: { isFetching: false } }) await dispatch({ type: LOGIN_PENDING, data: { isFetching: true } }) if(wxLoginResult.code){ try { const apiLoginResult = await api.user.login({ code: wxLoginResult.code }); await dispatch({ type: LOGIN_SUCCESS, data: apiLoginResult }) wx.setStorageSync('token', apiLoginResult.data.token) } catch (error) { await dispatch({ type: LOGIN_FAIL, data: error }) } } else { await dispatch({ type: LOGIN_FAIL, data: wxLoginResult.errMsg }) } } ); // 仓库数据结构预定义 const initState = { wxApiPromisify: { isFinish: false }, wxSystemInfo: {}, wxUserInfo: {}, wxOnLaunch: {}, wxLogin: { code: null, token: null, userId: null, phone: null, errMsg: null }, userLogin: { isFetching: false, data: null } }; export const appReducer = (state = initState, action) => { switch (action.type) { case WX_API_PROMISIFY: return Object.assign({}, state, { wxApiPromisify: { isFinish: action.data } }); case WX_GET_CODE: return Object.assign({}, state, { wxLogin: action.data }); case WX_SYSTEM_INFO: return Object.assign({}, state, { wxSystemInfo: action.data}); case WX_USER_INFO: return Object.assign({}, state, { wxUserInfo: action.data}); case WX_ON_LAUNCH: return Object.assign({}, state, { wxOnLaunch: action.data}); case LOGIN_BEGIN: var userLogin = action.data; userLogin.isFetching = false; return Object.assign({}, state, { userLogin }); case LOGIN_PENDING: var userLogin = action.data; userLogin.isFetching = true; return Object.assign({}, state, { userLogin }); case LOGIN_SUCCESS: var userLogin = action.data; userLogin.isFetching = false; return Object.assign({}, state, { userLogin }); case LOGIN_FAIL: var userLogin = action.data; userLogin.isFetching = false; return Object.assign({}, state, { userLogin }); default: return state; } };

app.js 小程序启动入口