Created
December 6, 2018 06:09
-
-
Save amygrinn/c0f03152ac923aef59cf016917364d03 to your computer and use it in GitHub Desktop.
Redux and Vue
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Vue from 'vue'; | |
import * as Rx from 'rxjs/Rx'; | |
import * as VueRx from 'vue-rx'; | |
import Store from './store'; | |
// Import redux modules | |
import * as DeviceModule from './modules/device'; | |
const vueRx: any = VueRx; | |
Vue.use(vueRx.default, Rx); | |
Vue.mixin({ | |
beforeCreate() { | |
const options = this.$options; | |
// store injection | |
if (options.store) { | |
this.$store = options.store; | |
} else if (options.parent && options.parent.$store) { | |
this.$store = options.parent.$store; | |
} | |
} | |
}); | |
const store = new Store(); | |
store.injectReducer(DeviceModule.reducer); | |
store.runSaga(DeviceModule.saga); | |
new Vue({ | |
render: (h) => h(App), | |
router, | |
store | |
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { fromEventPattern, Observable, Observer } from 'rxjs'; | |
import { map } from 'rxjs/operators'; | |
import * as redux from 'redux'; | |
import createSagaMiddleware from 'redux-saga'; | |
export type Selector<T> = (state: any) => T; | |
// Add redux devtools extension if not in production mode or on branch 'beta' | |
declare var window: any; | |
const composeEnhancers = | |
((process.env.NODE_ENV !== 'production' || process.env.BRANCH === 'beta') && typeof window !== 'undefined') | |
? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || redux.compose | |
: redux.compose; | |
export default class Store implements redux.Store<any> { | |
private store: redux.Store<any>; | |
private reducers: redux.ReducersMapObject = {}; | |
private sagaMiddleware = createSagaMiddleware(); | |
constructor() { | |
this.store = redux.createStore( | |
this.getReducer(), | |
composeEnhancers( | |
redux.applyMiddleware(this.sagaMiddleware) | |
) | |
); | |
} | |
public select<T>(selector: Selector<T>): T { | |
return selector(this.getState()); | |
} | |
public select$<T>(selector: Selector<T>): Observable<T> { | |
return Observable.create((observer: Observer<T>) => { | |
const subscription = this.subscribe(() => { | |
observer.next(selector(this.getState())); | |
}); | |
return subscription; | |
}); | |
} | |
public dispatch(action: any) { | |
return this.store.dispatch({ ...action }); | |
} | |
public getState() { | |
return this.store.getState(); | |
} | |
public subscribe(listener: any) { | |
return this.store.subscribe(listener); | |
} | |
public replaceReducer(reducer: redux.Reducer<any>) { | |
return this.store.replaceReducer(reducer); | |
} | |
public injectReducer(reducerMap: redux.ReducersMapObject) { | |
this.reducers = { ...this.reducers, ...reducerMap }; | |
this.replaceReducer(this.getReducer()); | |
} | |
public runSaga(saga: () => Iterator<any>) { | |
this.sagaMiddleware.run(saga); | |
} | |
private getReducer(): redux.Reducer<any> { | |
return Object.keys(this.reducers).length > 0 | |
? redux.combineReducers(this.reducers) | |
: (state, action) => state; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment