這是有關React和Vue語法比較的第二篇文章。在本文中,將比較兩種生態系統中最著名的狀態管理庫(Redux和Vuex)的語法。javascript
Redux: redux.js.org/basics/stor…前端
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: vuex.vuejs.org/guide/vue
const store = new Vuex.Store({
state: { ... },
mutations: { ... }
})
...
new Vue({
el: '#app',
store,
});
複製代碼
Redux: redux.js.org/basics/acti…java
const ADD_TODO = 'ADD_TODO'
function addTodo(text) {
return {
type: ADD_TODO,
text,
}
}
複製代碼
Vuex: vuex.vuejs.org/guide/actio…react
const store = new Vuex.Store({
actions: {
increment (context) {
context.commit('increment') // commit a mutation to trigger state update
}
}
})
複製代碼
Redux(redux-thunk): redux.js.org/advanced/as…web
// 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: vuex.vuejs.org/guide/actio…vuex
actions: {
async fetchPosts ({ commit }) {
commit('requestPosts');
const res = await fetch('xxx');
commit('receivePosts', res);
},
}
複製代碼
Redux(reducer): redux.js.org/basics/redu…chrome
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): vuex.vuejs.org/guide/mutat…json
const store = new Vuex.Store({
mutations: {
addTodo (state, payload) {
state.todos = [
...state.todos,
{ text: payload.text, completed: false }
]
}
}
})
複製代碼
Redux(combine-reducers): redux.js.org/api/combine…
import { combineReducers } from 'redux'
const reducers = combineReducers({
reducerA,
reducerB,
})
export default reducers
複製代碼
Vuex(modules): vuex.vuejs.org/guide/modul…
const moduleA = {
state: { ... },
mutations: { ... },
actions: { ... },
getters: { ... }
}
const moduleB = {
state: { ... },
mutations: { ... },
actions: { ... }
}
const store = new Vuex.Store({
modules: {
a: moduleA,
b: moduleB
}
})
複製代碼
Redux: redux.js.org/basics/usag…
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: vuex.vuejs.org/guide/state…
import { mapState } from 'vuex'
export default {
computed: {
...mapState(['count']),
}
}
複製代碼
action: vuex.vuejs.org/guide/actio…
import { mapActions } from 'vuex'
export default {
methods: {
...mapActions(['increment']),
}
}
複製代碼
Redux(middleware): redux.js.org/advanced/mi…
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): vuex.vuejs.org/guide/plugi…
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): redux.js.org/recipes/com…
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: vuex.vuejs.org/guide/gette…
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 chrome.google.com/webstore/de…
Vuex chrome.google.com/webstore/de…
來源:medium.com/js-dojo,做者:Oahehc (Andrew),翻譯:公衆號《前端全棧開發者》