由于Vuex和Redux都是从Flux中衍生出来,同时Vuex对Redux部分思想也有一些借鉴,所以Vuex和Redux有很多相同点。很多资料也有介绍两者的对比,但大部分讲解的比较抽象,较难理解。笔者整理两者异同点,同时配有标准案例进行说明。注意本文不是科普vuex和redux相关概念,相关知识内容可以在官方文档中查看。Vuex (opens new window) 、Redux (opens new window)
vuex
定义了state、getter、mutation、action
四个对象;redux
定义了state、reducer、action
。
vuex
中state
统一存放,方便理解;redux
state依赖所有reducer的初始值vuex
有getter
,目的是快捷得到state;redux
没有这层,react-redux mapStateToProps参数做了这个工作。vuex
中mutation
只是单纯赋值(很浅的一层);redux
中reducer
只是单纯设置新state(很浅的一层)。他俩作用类似,但书写方式不同vuex
中action
有较为复杂的异步ajax请求;redux
中action中可简单可复杂,简单就直接发送数据对象({type:xxx, your-data}),复杂需要调用异步ajax(依赖redux-thunk插件)。vuex触发方式
有两种commit同步和dispatch异步;redux
同步和异步都使用dispatch唯一
可以带上数据修改state的触发对象。接下逻辑就转移到reducer中注:也可以反过来理解:Vuex的每一次this.$store.commit('type', data) === action(data){ return { type, data}})
简单理解,reducer承担了state和mutations功能。 Vuex中commit-mutations是唯一修改state的方式;Redux中dispatch-reducer是唯一修改state方式
// vuex非常简单易懂,而且整理到1个文件即可
const state: IState = {
login: false,
option: {
_id: '',
sub_title: '',
title: '',
keyword: '',
descript: '',
url: '',
email: '',
icp: ''
}
}
const actions: ActionTree<IState, any> = {
// 登录
async login ({ commit }, user: StoreState.Login): Promise<Ajax.AjaxResponse> {
commit('USER_LOGINING')
const res: Ajax.AjaxResponse = await service.login({ ...user })
commit('USER_LOGINING_FINAL')
return res
},
}
const mutations: MutationTree<IState> = {
'USER_LOGINING' (state: IState): void {
state.login = true
},
'USER_LOGINING_FINAL' (state: IState): void {
state.login = false
},
}
export default new Vuex.Store({
state,
actions,
mutations,
modules
})
// store.js
import { createStore, combineReducers, applyMiddleware } from 'redux'
import home from './home/reducer'
import demo from './demo/reducer'
import thunk from 'redux-thunk'
// reducers获得初始state
let store = createStore(combineReducers({ home, demo }), applyMiddleware(thunk))
export default store
// reducer.js
let defaultState = {
demoList: []
}
export default (state = defaultState, action) => {
switch (action.type) {
case 'setDemoList':
return { ...state, demoList: action.list }
default:
return state
}
}
// action.js
// 同步action
export const setDemoList = list => ({
type: 'setDemoList',
list
})
// 异步action
export const setAsyncList = () => {
return async dispatch => {
let result = await API.getXXX()
dispatch({type: 'setAsyncList', result})
}
}
// ui
const mapStateToProps = (state) => {
return {
list: state.demo.demoList
}
}
// const mapDispatchToProps = (dispatch) => {
// return {
// setDemoList: list => dispatch(setDemoList(list))
// }
// }
// or
const mapDispatchToProps = {setDemoList}
export default connect(mapStateToProps, mapDispatchToProps)(Demo)