@subject: wepy-redux-time-todo
@author: leinov
@date:2018-10-30
@notice: 小程序(wepy)開發群110647537 歡迎加入
wepy-redux-time-todo
Use github地址
git clone git@github.com:leinov/wepy-redux-time-todo.git
npm install
npm run dev
添加到微信開發者工具里即可運行
Wiki
創建項目
wepy是騰訊自出的一套小程序框架,基於Vue寫法,也可以靈活使用第三方庫,對原生的api也做了部分優化,提高了整體代碼的可讀性和可維護性,也極大的提高了開發效率,極力推薦使用。首先需要安裝wepy命令,通過命令創建wepy項目,在執行下面第二句命令過程中會有一些問題,在到是否使用redux的問題時選y,在創建時就會加入redux依賴以及store文件夾
npm install wepy-cli -g //安裝全局wepy命令
wepy init standard wepy-redux-time-todo // 創建wepy-redux-time-todo項目
項目結構
執行創建命令后會出現類似以下結構的項目結構(下面是我自己創建文件后的)
|-- dist // 編譯后執行文件夾
|-- node_modules
|-- src // 開發文件夾
| |-- components //組件
|-- sec-title.wpy
|-- pages //業務頁面
|-- index.wpy
|-- store // redux
|-- actions
|-- index.js
|-- reducers
|-- timeReducer.js
|-- index.js //合並reducer
|-- types
|-- index.js
|-- style //樣式
|-- weui.scss
|-- app.wpy //入口
|-- package.json
Redux概念以及使用
Redux主要的作用是管理復雜的數據,多用於操作單頁應用中的復雜狀態,將整個應用的狀態集中放在一個容器里統一管理。作為一個狀態容器,他就像一個盒子(store),這個唯一的盒子(整個應用只有一個store)里有很多狀態(state), 都以一個對象樹的形式儲存在store 中。 唯一能改變 state 的辦法是觸發 action,action是一個簡單的對象,用來描述你想要干什么。reducer是一個純函數來根據action返回的type操作狀態變化返回新狀態,reducer作為createStore參數返回最新的store,下面我們通過redux官網的代碼具體描述redux的執行過程,
Action
action可以理解為動作,用戶希望干什么,比如點擊一個按鈕讓頁面的數字加1,切換日期,插入數組等,總之是一個希望頁面狀態發生改變的行為標識。action用一個對象表示,包含一個必須屬性type
{type:"INCREMENT"} //表示添加動作
{type:"DECREMENT"} //表示減法動作
{type:"GET_DATA",payload:{}} // 表示獲取數據動作並掛載一個數據在payload屬性上供reducer使用,多用於異步獲取數據,也可以用自己的添加其他屬性
Reducer
reducer是一個形式為 (state, action) => state 的純函數(純函數概念:不依賴外部環境變量,只依賴內部參數、不會產生副作用、相同的輸入確保相同的輸出)。描述了 action 如何把 state 轉變成下一個 state。state 的形式取決於你自己,可以是基本類型、數組、對象、甚至是 Immutable.js 生成的數據結構。唯一的要點是當 state 變化時需要返回全新的對象,而不是修改傳入的參數。
下面例子使用 switch
語句和字符串來做判斷,也可以用自己的方式。
function reducer(state = 0, action) {
switch (action.type) {
case 'INCREMENT':
return state + 1;
case 'DECREMENT':
return state - 1;
default:
return state;
}
}
store
redux的createStore方法用於創建應用唯一的store,createStore方法的參數即reducer,用於更新store內state樹,通過以下創建就可以把一個初始的{state:0}的這樣一個狀態存入到store中
import { createStore } from 'redux';
const store = createStore(reducer);
store有幾個重要的方法
store.dispatch(action)
//派發事件 表示要干什么store.getState()
// 獲取存儲在store里的所有狀態(數據)store.subscribe(listener)
//手動監聽狀態變化
dispatch改變狀態
store.dispatch是改變狀態的唯一方式,dispatch接受一個action參數(做什么),通知reducer需要做出什么樣的改變,再更新整個store
store.dispatch({INCREMENT:"INCREMENT"})
這個操作會告訴reducer 當前需要給state做加1操作,
獲取state
store.getState() // {state:1}
subscribe監聽
store.subscribe(() =>
console.log(store.getState())
);
在dispatch觸發狀態更新后需要通過subscribe監聽才能獲得最新的狀態,如果在react中使用則需要把視圖渲染函數放在監聽函數內。
import store from "./redux.js"
store.subscribe(()=>{
ReactDOM.render(<App />, document.getElementById('root'))
});
以上是純redux的使用,使用起來比較雞肋,redux大量被使用在react項目中,封裝庫react-redux提供的Provider和connect可以將react和redux完美結合,使用非常方便。
Redux在wepy中的使用
通過上面的描述應該對redux有了一定的了解,接下來我們看下redux在小程序框架wepy中如何使用,wepy中需要安裝wepy-redux依賴,類似react-redux,store文件夾下放redux的操作代碼,redux的使用方法都相同,這里我們講下與react使用不一樣的地方
初始化store
首先需要在app.wpy中初始化store
import { setStore } from 'wepy-redux'
import configStore from './store'
const store = configStore()
setStore(store)
wepy中app.wpy編譯后為原生小程序中的app.js,app.js在小程序整個執行生命周期里處於最前端,在小程序初始化時來創建store,這樣在所有頁面都可以使用,等同於react里的Provider
redux-actions
這里使用redux-actions
庫來優化reducer里的switch
寫法。
import { handleActions } from "redux-actions";
import {
TIME_CONFIG_DATA, // 學員
} from "../types/index";
export default handleActions({
[TIME_CONFIG_DATA](state, action) {
return {
...state,
timeConfigData: action.newData
};
}
}, {
timeConfigData:[], //state初始值
});
connect連接到wepy組件上
connect(states, actions) connect有兩個參數,states是整個應用的狀態,頁面需要使用哪個狀態對應獲取該狀態即可,actions業務操作,是wepy-redux對action的封裝,這里我們不用這種方式,自己在action中手動dispatch,如果想要了解詳細使用可參考wepy-redux
import { connect } from 'wepy-redux'
@connect({
timeConfigData(state) {
return state.timeReducer.num
}
})
export default class Index extends wepy.page {
// ...
methods = {
// ...
}
// ...
onLoad() {
}
}
使用數據
<template lang="wxml">
<repeat for="{{timeConfigData}}" index="index" item="item" key="key">
</repeat>
</template>
其他方法都與在react中使用相同,通過上面的配置就可以在wepy中使用redux了,詳細代碼參考code