Home

Awesome

轻量级的 Redux 封装

Make Redux as simple as Vuex

示例项目

使用

npm install vuex-redux

特性

  1. 目录结构(使用modules来拆分各个reducer,参照vuex module
  2. 不需要手动编写action
  3. 提供namespace,参照 vuex namespace
  4. 内置 immer,既能享受便捷的mutable方式去操作state,又能享受immutable带来的状态可预测和方便做性能优化的优点

目录结构

modules / counter.js

import { createModel } from "vuex-redux";

const model = {
  namespace: 'counter',
  state: {
    count: 10
  },
  reducer: {
    add(state, action) {
      state.count += 1
    },
    minus(state, action) {
      state.count--
    },
  }
}

export default createModel(model)

modules / todo.js

import { createModel } from "vuex-redux";

const model = {
  namespace: 'todo',
  state: {
    todoList: []
  },
  reducer: {
    addTodo(state, action) {
      state.todoList.push(action.data)
    },
    delete(state, action) {
      state.todoList.splice(action.data, 1)
    },
  },
}

export default createModel(model)

index.js

import { createStore, combineReducers, applyMiddleware } from "redux";
import { composeWithDevTools } from 'redux-devtools-extension';
import { setActionToStore, storeEnhancer } from "vuex-redux";

import todo from "./modules/todo";
import counter from "./modules/counter";

const loggerMiddleware = store => dispatch => action => {
  console.log("action", action)
  dispatch(action)
}

const reducerModules = {
  todo,
  counter,
}


const store = createStore(combineReducers(reducerModules), composeWithDevTools(
  applyMiddleware(loggerMiddleware),
  storeEnhancer
  // other store enhancers if any
));

setActionToStore(store, reducerModules)
export default store

组件这样使用

// dispatch 支持两种使用方式
// 原生redux调用: dispatch({type:'add',payload:{}})
// 类似vuex调用: dispatch('add',payload)

// 调用 counter 的 add
dispatch(store.counter.add)//类似 vuex调用

dispatch({ //原生redux调用
  type:store.counter.add,
})

// 调用 todo 的 delete
dispatch(store.counter.add,{})//类似 vuex调用

dispatch({//原生redux调用
  type:store.counter.delete,
  payload:{}
})

对比传统的redux使用方式

目录结构

action.js

export const ADD = 'add'
export const MINUS = 'minus'
export const ADD_TODO = 'addTodo'

reducer / todo.js

import { ADD_TODO } from './action.js'

export function todoReducer(state = { todoList:[] }, action) {
  switch (action.type) {
    case ADD_TODO:
      return {
        ...state,
        todoList:[...state.todoList,action.payload]
      }
    default:
      return state
  }
}

reducer / counter.js

import { ADD, MINUS } from './action.js'
export function counterReducer(state = { count:0 }, action) {
  switch (action.type) {
    case ADD:
      return {
        ...state,
        count:state.count + 1
      }
    case MINUS:
       return {
        ...state,
        count:state.count - 1
      }
    default:
      return state
  }
}

index.js

import { createStore, combineReducers, applyMiddleware } from "redux";
import { composeWithDevTools } from 'redux-devtools-extension';
import todo from "./reducer/todo.js";
import counter from "./reducer/counter.js";

const reducerModules = {
  todo,
  counter,
}

const loggerMiddleware = store => dispatch => action => {
  console.log('loggerMiddleware')
  dispatch(action)
}


const store = createStore(combineReducers(reducerModules), composeWithDevTools( // use redux-devtools
  applyMiddleware(loggerMiddleware),
  // other store enhancers if any
));

export default store