Skip to content

Instantly share code, notes, and snippets.

@amygrinn
Created December 6, 2018 06:09
Show Gist options
  • Save amygrinn/c0f03152ac923aef59cf016917364d03 to your computer and use it in GitHub Desktop.
Save amygrinn/c0f03152ac923aef59cf016917364d03 to your computer and use it in GitHub Desktop.
Redux and Vue
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
});
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