这是无关React和Vue语法比拟的第三篇文章。在本文中,将比拟两种生态系统中最驰名的状态治理库(Redux和Vuex)的语法。
其它两篇:
- React.js和Vue.js的语法并列比拟
- Next.js和Nuxt.js的语法比拟
议程
- 创立Store
- Action
- 异步Action
- Reducer | Mutation
- Combine-Reducers | Modules
- Connect-with-Component
- 中间件 | 插件
- Selector | Getter
- DevTools
创立Store
Redux: https://redux.js.org/basics/s...
import React from 'react'import { render } from 'react-dom'import { Provider } from 'react-redux'import { createStore } from 'redux'import todoApp from './reducers'import App from './components/App'const store = createStore(todoApp)render( <Provider store={store}> <App /> </Provider>, document.getElementById('root'))
Vuex: https://vuex.vuejs.org/guide/
const store = new Vuex.Store({ state: { ... }, mutations: { ... }})...new Vue({ el: '#app', store,});
Action
Redux: https://redux.js.org/basics/a...
const ADD_TODO = 'ADD_TODO'function addTodo(text) { return { type: ADD_TODO, text, }}
Vuex: https://vuex.vuejs.org/guide/...
const store = new Vuex.Store({ actions: { increment (context) { context.commit('increment') // commit a mutation to trigger state update } }})
异步Action
Redux(redux-thunk): https://redux.js.org/advanced...
// apply redux-thunkimport thunkMiddleware from 'redux-thunk'const store = createStore( rootReducer, applyMiddleware(thunkMiddleware))...export function fetchPosts() { return function (dispatch) { dispatch(requestPosts()) return fetch('xxx') .then(response => response.json()) .then(json => dispatch(receivePosts(json))) }}
Vuex: https://vuex.vuejs.org/guide/...
actions: { async fetchPosts ({ commit }) { commit('requestPosts'); const res = await fetch('xxx'); commit('receivePosts', res); },}
Reducer | Mutation
Redux(reducer): https://redux.js.org/basics/r...
const initialState = { todos: [],}function todoApp(state = initialState, action) { switch (action.type) { case ADD_TODO: return { ...state, todos: [ ...state.todos, { text: action.text, completed: false, } ], } default: return state }}
Vuex(mutation): https://vuex.vuejs.org/guide/...
const store = new Vuex.Store({ mutations: { addTodo (state, payload) { state.todos = [ ...state.todos, { text: payload.text, completed: false } ] } }})
Combine-Reducers | Modules
Redux(combine-reducers): https://redux.js.org/api/comb...
import { combineReducers } from 'redux'const reducers = combineReducers({ reducerA, reducerB,})export default reducers
Vuex(modules): https://vuex.vuejs.org/guide/...
const moduleA = { state: { ... }, mutations: { ... }, actions: { ... }, getters: { ... }}const moduleB = { state: { ... }, mutations: { ... }, actions: { ... }}const store = new Vuex.Store({ modules: { a: moduleA, b: moduleB }})
Connect-with-Component
Redux: https://redux.js.org/basics/u...
import { connect } from 'react-redux'import { addTodo } from '../actions'import TargetComp from '../components/TargetComp'// stateconst mapStateToProps = (state, ownProps) => { return { todos: state.todos, }}// actionconst mapDispatchToProps = (dispatch, ownProps) => { return { addTodo: (text) => { dispatch(addTodo(text)) } }}const TargetContainer = connect(mapStateToProps, mapDispatchToProps)(TargetComp)export default TargetContainer
Vuex
state: https://vuex.vuejs.org/guide/...
import { mapState } from 'vuex'export default { computed: { ...mapState(['count']), }}
action: https://vuex.vuejs.org/guide/...
import { mapActions } from 'vuex'export default { methods: { ...mapActions(['increment']), }}
中间件 | 插件
Redux(middleware): https://redux.js.org/advanced...
import { createStore, combineReducers, applyMiddleware } from 'redux'const logger = store => next => action => { console.log('dispatching', action) let result = next(action) console.log('next state', store.getState()) return result}const todoApp = combineReducers(reducers)const store = createStore( todoApp, applyMiddleware(logger))
Vuex(plugin): https://vuex.vuejs.org/guide/...
const myPluginWithSnapshot = store => { let prevState = _.cloneDeep(store.state) store.subscribe((mutation, state) => { let nextState = _.cloneDeep(state) // compare `prevState` and `nextState`... // save state for next mutation prevState = nextState })}const store = new Vuex.Store({ ..., plugins: process.env.NODE_ENV !== 'production' ? [myPluginWithSnapshot] : [],})
Selector | Getter
Redux(reselect): https://redux.js.org/recipes/...
import { createSelector } from 'reselect'const getTodos = state => state.todosexport const getDoneTodos = createSelector( [getTodos], todos.filter(t => t.completed),)...import { connect } from 'react-redux'import TodoList from '../components/TodoList'import { getDoneTodos } from '../selectors'const mapStateToProps = state => { return { doneTodos: getDoneTodos(state) }}const DoneTodoList = connect(mapStateToProps)(TodoList)export default DoneTodoList
Vuex: https://vuex.vuejs.org/guide/...
const store = new Vuex.Store({ state: { ... }, getters: { doneTodos: state => { return state.todos.filter(t => t.completed) } }})...import { mapGetters } from 'vuex'export default { computed: { ...mapGetters(['doneTodos']) }}
DevTools
Redux
https://chrome.google.com/web...
Vuex
https://chrome.google.com/web...
起源:https://medium.com/js-dojo,作者:Oahehc (Andrew),翻译:公众号《前端全栈开发者》