ankurk91 / vue-loading-overlay

Vue.js component for full screen loading indicator :cyclone:
https://ankurk91.github.io/vue-loading-overlay/
MIT License
1.24k stars 101 forks source link

How to use it with vue router #21

Closed NaturalDevCR closed 6 years ago

NaturalDevCR commented 6 years ago

Hi, thanks a lot for this, i'm just wondering how can i use this alongside with vue router, i want to show the spinner on each load, thanks in advance.

NaturalDevCR commented 6 years ago

Right now i have this code:

main.js

 //Form Loading
 import Loading from 'vue-loading-overlay';
 // Import stylesheet
 import 'vue-loading-overlay/dist/vue-loading.min.css';
 Vue.use(Loading);

//jQuery
 window.$ = require('jquery')
 window.JQuery = require('jquery')

// Plugins
import App from './App.vue'
import Chartist from 'chartist'

// router setup
import routes from './routes/routes'

// plugin setup
Vue.use(VueRouter)
Vue.use(DashboardPlugin)
Vue.use(require('vue-moment'));

// configure router
const router = new VueRouter({
    routes, // short for routes: routes
    linkExactActiveClass: 'nav-item active'
});

//here comes the loader

router.beforeResolve((to, from, next) => {

    // If this isn't an initial page load.
    if (to.name) {
        // Start the route progress bar.
        let loader = Loading.show({

        });
    }
    next()
})

router.afterEach((to, from) => {
    // Complete the animation of the loader
    let loader = Loading.hide()
})
ankurk91 commented 6 years ago
Vue.use(Loading);

// Variable that holds loader instance

let loader = null;
function hideLoader(){
   // destroy previous
     if(loader) { 
         loader.hide(); 
         loader = null; 
    }
}

function showLoader(){
     hideLoader();
     loader = Vue.$loading.show()
}
router.beforeResolve((to, from, next) => {
    // If this isn't an initial page load.
    if (to.name) {
       showLoader();
    }
    next()
})

router.afterEach((to, from) => {
    // Complete the animation of the loader
    hideLoader()
})

Remember

NaturalDevCR commented 6 years ago

Hi @ankurk91 , thanks in advance for your help, i'm getting errors with the hideLoader() function:

Syntax Error: Invalid left-hand side in assignment expression

it's about this part:

loader && loader.hide() && loader = null;

ankurk91 commented 6 years ago
loader && loader.hide() && loader = null;

you can simplify this line in your app. it is checking if an loader exists and if exists the hide it, finally it sets its value to null

NaturalDevCR commented 6 years ago

but it's throwing the error:

Syntax Error: Invalid left-hand side in assignment expression

any ideas what would be the issue? or is it there another way to do it?

ankurk91 commented 6 years ago

I said you need to simplify this line according to your application. Did you read my comment.

if loader exists {

# hide the loader
# set loader value to null

}
NaturalDevCR commented 6 years ago

Thanks @ankurk91, that made the trick :)

nawalnew commented 5 years ago

Hey @ankurk91 and @LaravDev ,

I tried to get this to work and put the whole code in my main.js . Everything is fine. But the Problem is, the Loader dont get triggered.

And when i put in my App.vue than I get a error.

[Vue warn]: Unknown custom element: <loading> - did you register the component correctly? For recursive components, make sure to provide the "name" option.

What is the next step after put in this code in main.js? Im frustrated :/ Console.Logs are showing up, but no spinner.

I think I miss one Step to call the loader itself for my whole application in App.vue

Thank you in advance :)

ankurk91 commented 5 years ago

@nawalnew

Can not help you unless you share your code sample. https://codesandbox.io

nawalnew commented 5 years ago

Hello I post it here if thats okay. I think its just a small problem with global configuration and triggering the overlay

Main.js

// Import component
    import Loading from 'vue-loading-overlay';
    // Import stylesheet
    import 'vue-loading-overlay/dist/vue-loading.css';

Vue.component('Loading', Loading)
    Vue.use(Loading);

Vue.config.productionTip = false;

/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  components: { App, Loading },
  template: '<App/>',
});

let loader = null;
function hideLoader(){
   // destroy previous
   console.log('2')
     if(loader) {
         loader.hide();
         loader = null;
    }
}

function showLoader(){
    console.log('1')
     hideLoader();
     loader = Vue.$loading.show()
}

router.beforeEach((to, from, next)=>{

  if (to.name) {
      showLoader();
   }
   next()
})
**router.afterEach((to, from)=>{

setTimeout(() => {
   loader.hide()
    },1300)
  // store.commit('setLoading', false)
})**

I found out what the Problem was.

router.afterEach is triggered too fast, almost instant. With a delay I can see now the spinner.

But the Problem is that I need this Component to wait until all is loaded before this stops.

Ive found out That I can do the stop of the spinner with the mounted() function.

But my Problem is: How can I trigger the "loader.hide()" function in my App.vue?

mounted(){
  // loader.hide()
  console.log('Finished')

  },

THANK YOU :)

nya1 commented 5 years ago

@nawalnew

A quick way to pass data from router to components is to use Vue.prototype, from your example you can do:

router.beforeEach((to, from, next)=>{
  if (to.name) {
      showLoader();
   }
   // set hideLoader function
   Vue.prototype.$hideLoader = hideLoader
   next()
})

Component:

mounted () {
    this.$hideLoader()
}
nawalnew commented 4 years ago

@nawalnew

A quick way to pass data from router to components is to use Vue.prototype, from your example you can do:

router.beforeEach((to, from, next)=>{
  if (to.name) {
      showLoader();
   }
   // set hideLoader function
   Vue.prototype.$hideLoader = hideLoader
   next()
})

Component:

mounted () {
    this.$hideLoader()
}

Thank you very much. This works. :)