微信小程序开发之手把手教你在小程序里使用 Redux
白羽 2018-07-18 来源 :网络 阅读 905 评论 0

摘要:本文将带你了解微信小程序开发之手把手教你在小程序里使用 Redux,希望本文对大家学微信有所帮助。



具体实现

运行我们的项目,发现官网已经给了我们一些 Redux 的使用方法,实际上主要是放在 store文件夹下面了,我们现在来一探究竟~

step1

入口文件 index.js ,里面主要是 初始化 Redux , 其中 promiseMiddleware 是一个中间件,方便后面 action 做异步处理~ reducers 是一个纯函数,用于接受 Action 和当前 State作为参数,返回一个新的 State ~

import { createStore , applyMiddleware } from 'redux'import promiseMiddleware from 'redux-promise'import reducer from './reducers'const Store = createStore(
reducer ,
applyMiddleware(promiseMiddleware)
)export default configStore => Store

step2

剩下三个文件夹分别是 types reducers 和 actions ,其中 types 用于定义我们要触发的 action 的名称,也就是表示 action 的名称,这里我定义了 counter 和 list 两个 types ,内容分别如下:

counter.js

export const INCREMENT = 'INCREMENT'export const DECREMENT = 'DECREMENT'export const ASYNC_INCREMENT = 'ASYNC_INCREMENT'

list.js

export const ADD = 'ADD'export const REMOVE = 'REMOVE'

最后通过 types 文件夹的入口文件 index.js 将他们暴露出去~

export * from './counter'export * from './list'

step3

reducers 文件件存放我们的纯函数,用来更改我们的状态 , 他也有一个入口文件 index.js,定义如下:

import { combineReducers } from 'redux'
   import counter from './counter'
   import list from './list'
   
   export default combineReducers({
    counter ,
    list
   })

首先将 counter 和 list 的分别引入进来,通过 redux 定义的 combineReducers 函数,将所有的 reducers 合并成一个整体,方便我们后面对其进行管理!

那么 counter 和 list 对应的 reducer 分别是 什么样的?我们直接看代码:

counter.js

import { handleActions } from 'redux-actions'
   import { INCREMENT , DECREMENT , ASYNC_INCREMENT } from '../types/counter'
   
   const defaultState  = {
    num: 0 ,
    asyncNum: 0
   }
   
   export default handleActions({
    [INCREMENT](state){
    return{
    ...state,
    num : state.num + 1
    }
    },
    [DECREMENT](state){
    return{
    ...state,
    num : state.num - 1
    }
    },
    [ASYNC_INCREMENT](state, action){
    return {
    ...state ,
    asyncNum : state.asyncNum + action.payload
    }
    }
   },defaultState)

我们介绍一下 counter.js 里面的 reducer , 首先引入了 handleActions 方法用来创建 actions , 它将多个相关的 reducer 写在一起也是 ,方面后期维护,也方便后期通过 dispatch来调用他们更改 state 里面的状态,它主要接收两个参数,第一个参数时候个大对象,里面存放多个 reducer , 第二个参数是初始化的时候 state 的状态值,因此,我们一开始就定义了 defaultState ;

接着,我们看看里面的 reducer , 分别定义了 INCREMENT 、 DECREMENT 和 ASYNC_INCREMENT 三个 reducer ,前两个比较简单,分别是对 state 里面的 num 值进行 加减操作 , 最后一个是通过 action.payload 的值来对 asyncNum 的值进行异步操作的,具体怎么做到的,我们一会再看~

list.js 里定义的 reducer 跟上面类似,我就不一一介绍了,直接贴代码即可~

list.js

import { handleActions } from 'redux-actions'
   import { ADD , REMOVE } from '../types/list'
   
   const defaultState = [
    {
    title : '吃饭' ,
    text : '今天我要吃火锅'
    },
    {
    title : '工作' ,
    text : '今天我要学习Redux'
    }
   ]
   
   export default handleActions({
    [ADD]( state , action ){
    state.push(action.payload)
    return [...state]
    },
    [REMOVE]( state , action ){
    state.splice( action.payload , 1 );
    return [ ...state ]
   
    }
   },defaultState)

step4

我们终于走到这一步了,到这里,你已经离预期不远啦,就剩一个 actions 文件件了,毫不例外,入口文件 index.js 如下:

index.js

export * from './counter'

很简单,只需要将所需的 action 导出即可~

这个里面我只定义了 counter 的 action , 也就是为了刚才异步数据 asyncNum 准备的~

counter.js

import { ASYNC_INCREMENT } from '../types/counter'
   import { createAction } from 'redux-actions'
   
   export const asyncInc = createAction(ASYNC_INCREMENT,()=>{     return new Promise(resolve=>{
    setTimeout(()=>{
    resolve(1)
    },1000)
    })
   })

这里跟 reducer 里面的要区分,这里是可以对数据进行一系列处理的,我们通过 createAction 创建一个 action , 该方法主要有两个参数,第一个参数 type 表示 action 的类型,第二个参数 payloadCreator 是一个 function ,处理并返回需要的 payload ;如果空缺,会使用默认方法。这里我们是延迟 1s 后返回一个 1 ;

ok,到此为止,你已经基本完成了一个 redux 的容器~

接下来,就是展示它怎么使用的时候了~

step5

我们创建一个 index.wpy 的文件,这里我把代码直接贴出来,然后慢慢来分析看看~

代码如下:

<template lang="wxml">       <view class="container">         <text>同步{{ num }}</text>         <text>异步{{ asyncNum }}</text>         <button @tap="increment" type="primary">加一</button>         <button @tap="decrement" type="primary">减一</button>         <button @tap="asyncIncrement" type="primary">异步加一</button>              <button @tap="addList">添加</button>              <view class="box">             <view class="item" wx:for-items="{{ todoList }}" wx:key="index">                 <view class="title">{{ item.title }}</view>                 <view class="content">{{ item.text }}</view>                 <button type="primary" class="delete" @tap="delete({{index}})">删除</button>             </view>         </view>            </view>          </template>          <script>     import wepy from 'wepy'     import { connect } from 'wepy-redux'     import { INCREMENT , DECREMENT } from '../store/types/counter'     import { asyncInc } from '../store/actions'           @connect({     num(state){     return state.counter.num;     },     asyncNum(state){     return state.counter.asyncNum;     }     },{     increment : INCREMENT ,     decrement : DECREMENT ,     asyncIncrement : asyncInc     })           export default class Index extends wepy.page {           components = {}           computed = {     todoList(){     return wepy.$store.getState().list;     }         }              methods = {     delete(index){     wepy.$store.dispatch({ type : 'REMOVE' , payload : index })                 },     addList(){     wepy.$store.dispatch({ type : 'ADD' , payload : {     title : '学习' ,                     text : '好好学习'                 }})             }         }           onLoad () {     console.log(wepy.$store.getState())     } }     </script>               <style lang="less">         text{             display: block;             text-align: center;             margin: 10px auto;         }         button{             width: 90%;             display: block;             margin: 10px auto;         }              .item{             display: flex;             align-items: center;             text-align: center;             padding: 0 15px;             .title{                 font-size: 14px;                 line-height: 20px;                 margin: 10px auto;             }             .content{                 font-size: 15px;                 flex: 1;             }                  .delete{                 width: 70px;                 height: 40px;                 line-height: 40px;             }         }     </style>


样式结构方面我们这里不做讨论,主要看 js 部分,其中 import { INCREMENT , DECREMENT } from '../store/types/counter' 和 import { asyncInc } from '../store/actions'分别表示从 counter 和 actions 导出所需的 action

我们重点看看 从 wepy-redux 中 引入的 connect ,这个 connect 很关键,它是连接 组件 和 状态 的桥梁,主要用法是 @connect(states, actions) ~

states : 访问 state 上的值,可以是数组或者对象,如果是对象的话,则包含的是 K-V对, V 可以是函数还可以是字符串,如果是字符串的话则默认获取 state[V] , 否则的话则是使用返回值;而对于如果是数组的话(数组中的项只能为字符串),则认为是相同的 K-V 对象结构。 states 最终会附加到组件的 computed 属性值上。


本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标移动开发之微信频道!

本文由 @白羽 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程