这是有关React和Vue语法比较的第三篇文章。在本文中,将比较两种生态系统中最著名的状态管理库(Redux和Vuex)的语法。
其它两篇:
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, });
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 } } })
Redux(redux-thunk): https://redux.js.org/advanced...
// apply redux-thunk import 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); }, }
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 } ] } } })
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 } })
Redux: https://redux.js.org/basics/u...
import { connect } from 'react-redux' import { addTodo } from '../actions' import TargetComp from '../components/TargetComp' // state const mapStateToProps = (state, ownProps) => { return { todos: state.todos, } } // action const mapDispatchToProps = (dispatch, ownProps) => { return { addTodo: (text) => { dispatch(addTodo(text)) } } } const TargetContainer = connect(mapStateToProps, mapDispatchToProps)(TargetComp) export default TargetContainer
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] : [], })
Redux(reselect): https://redux.js.org/recipes/...
import { createSelector } from 'reselect' const getTodos = state => state.todos export 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']) } }
Redux
https://chrome.google.com/web...
Vuex
https://chrome.google.com/web...
来源:https://medium.com/js-dojo,作者:Oahehc (Andrew),翻译:公众号《前端全栈开发者》