I am learning Vue after working for some time with Angular and I'd like to hear experienced programmers concerning the implementation of my Progressive Bar service (in Vue it's called Plugin).
The idea behind it is to have a solid service which is responsible for the progress bar indicator.
I've got there a component with the logic for displaying and hiding and CSS with HTML Mark-up. And the core which serves as a middleware (or a service in Angular) between the component and Providers (vueRouter and Apollo).
I wasn't sure if it's a good practice to use RxJS in Vue. I've always thought that it's reactive itself but here I found it useful to have it. Is it a good practice?
It's still raw. Later on I'd like to make it customizable with options, but for now I'd like to know if I'm on the right way.
main.js
import Vue from "vue";
import VueRx from 'vue-rx'
import App from "./App.vue";
import router from "./router";
import store from "./store";
import { createProvider } from './vue-apollo'
import ProgressBar from '@/plugins/progressBarPlugin';
Vue.use(ProgressBar);
Vue.use(VueRx)
Vue.config.productionTip = false;
export default new Vue({
router,
store,
apolloProvider: createProvider(),
render: h => h(App)
}).$mount("#app");
index.js (progressBarPlugin)
import ProgressBarComponent from './progress-bar/progress-bar.vue';
import apolloHook from './apolloHook.js';
import vueRouterHook from './vueRouterHook.js';
import { Subject } from 'rxjs'
import { distinctUntilChanged } from 'rxjs/operators'
export const state = new Subject().pipe(distinctUntilChanged());
const ProgressBarPlugin = {
install(Vue) {
Vue.component(ProgressBarComponent.name, ProgressBarComponent);
Vue.mixin({
created() {
if (this.$options.name === ProgressBarComponent.name) {
apolloHook(state, this.$apolloProvider);
vueRouterHook(state, this.$router)
}
}
})
},
request() {
state.next('request');
},
response() {
state.next('response');
},
done() {
state.next('done');
}
};
export default ProgressBarPlugin;
apolloHook
export default function apollo(state, apolloProvider) {
if (apolloProvider) {
apolloProvider.watchLoading = function (loading) {
// This function can also accept param counter: -1 / 1
(loading) ? state.next('request') : state.next('done');
};
}
}
vueRouterHook
export default function vueRouter(state, router) {
if (router) {
router.beforeEach((to, from, next) => {
state.next('request');
next();
state.next('response');
})
router.afterEach(() => {
state.next('done');
})
}
}