BeforeRouteUpdate or Leave does not react in single file component












1














<template>
<div>
<top-loader ref="topLoader"></top-loader>
<div class="container">
<router-view></router-view>
</div>
</div>
</template>

<script>
import Toploader from '../global/Toploader.vue';
export default {
components: {
'top-loader': Toploader,
},
mounted () {
this.$refs.topLoader.start();
setTimeout(() => {
this.$refs.topLoader.done();
}, 2000)
//works here
},
beforeRouteUpdate (to, from, next) {
this.$refs.topLoader.done();
console.log(to);//not even this
next();
},
beforeRouteLeave (to, from, next) {
this.$refs.topLoader.start();
console.log(to);//not even this
next();
}
};
</script>


This is my single file component that is called in app.js:



require('./scripts/bootstrap');

window.Vue = require('vue');
import SFC from './components/SFC.vue'
import Routes from './routes/routes'
import VueRouter from 'vue-router'


Vue.use(VueRouter);

const router = new VueRouter({routes: Routes, mode: 'history'});

const app = new Vue({
el: '#root',
render: h => h(SFC),
router: router
});


I have 3 routes ('/', '/about', '/contact') inside routes file..
Nothing works with beforeRouteUpdate or Leave, but just if I add watcher for $route it does work...



Like this:



watch: {
$route(to, from) {
console.log('after', this.$route.path);
}
}


But this fires after route is loaded, I need one before it leaves current route and one after it load next route.



Any help?










share|improve this question





























    1














    <template>
    <div>
    <top-loader ref="topLoader"></top-loader>
    <div class="container">
    <router-view></router-view>
    </div>
    </div>
    </template>

    <script>
    import Toploader from '../global/Toploader.vue';
    export default {
    components: {
    'top-loader': Toploader,
    },
    mounted () {
    this.$refs.topLoader.start();
    setTimeout(() => {
    this.$refs.topLoader.done();
    }, 2000)
    //works here
    },
    beforeRouteUpdate (to, from, next) {
    this.$refs.topLoader.done();
    console.log(to);//not even this
    next();
    },
    beforeRouteLeave (to, from, next) {
    this.$refs.topLoader.start();
    console.log(to);//not even this
    next();
    }
    };
    </script>


    This is my single file component that is called in app.js:



    require('./scripts/bootstrap');

    window.Vue = require('vue');
    import SFC from './components/SFC.vue'
    import Routes from './routes/routes'
    import VueRouter from 'vue-router'


    Vue.use(VueRouter);

    const router = new VueRouter({routes: Routes, mode: 'history'});

    const app = new Vue({
    el: '#root',
    render: h => h(SFC),
    router: router
    });


    I have 3 routes ('/', '/about', '/contact') inside routes file..
    Nothing works with beforeRouteUpdate or Leave, but just if I add watcher for $route it does work...



    Like this:



    watch: {
    $route(to, from) {
    console.log('after', this.$route.path);
    }
    }


    But this fires after route is loaded, I need one before it leaves current route and one after it load next route.



    Any help?










    share|improve this question



























      1












      1








      1







      <template>
      <div>
      <top-loader ref="topLoader"></top-loader>
      <div class="container">
      <router-view></router-view>
      </div>
      </div>
      </template>

      <script>
      import Toploader from '../global/Toploader.vue';
      export default {
      components: {
      'top-loader': Toploader,
      },
      mounted () {
      this.$refs.topLoader.start();
      setTimeout(() => {
      this.$refs.topLoader.done();
      }, 2000)
      //works here
      },
      beforeRouteUpdate (to, from, next) {
      this.$refs.topLoader.done();
      console.log(to);//not even this
      next();
      },
      beforeRouteLeave (to, from, next) {
      this.$refs.topLoader.start();
      console.log(to);//not even this
      next();
      }
      };
      </script>


      This is my single file component that is called in app.js:



      require('./scripts/bootstrap');

      window.Vue = require('vue');
      import SFC from './components/SFC.vue'
      import Routes from './routes/routes'
      import VueRouter from 'vue-router'


      Vue.use(VueRouter);

      const router = new VueRouter({routes: Routes, mode: 'history'});

      const app = new Vue({
      el: '#root',
      render: h => h(SFC),
      router: router
      });


      I have 3 routes ('/', '/about', '/contact') inside routes file..
      Nothing works with beforeRouteUpdate or Leave, but just if I add watcher for $route it does work...



      Like this:



      watch: {
      $route(to, from) {
      console.log('after', this.$route.path);
      }
      }


      But this fires after route is loaded, I need one before it leaves current route and one after it load next route.



      Any help?










      share|improve this question















      <template>
      <div>
      <top-loader ref="topLoader"></top-loader>
      <div class="container">
      <router-view></router-view>
      </div>
      </div>
      </template>

      <script>
      import Toploader from '../global/Toploader.vue';
      export default {
      components: {
      'top-loader': Toploader,
      },
      mounted () {
      this.$refs.topLoader.start();
      setTimeout(() => {
      this.$refs.topLoader.done();
      }, 2000)
      //works here
      },
      beforeRouteUpdate (to, from, next) {
      this.$refs.topLoader.done();
      console.log(to);//not even this
      next();
      },
      beforeRouteLeave (to, from, next) {
      this.$refs.topLoader.start();
      console.log(to);//not even this
      next();
      }
      };
      </script>


      This is my single file component that is called in app.js:



      require('./scripts/bootstrap');

      window.Vue = require('vue');
      import SFC from './components/SFC.vue'
      import Routes from './routes/routes'
      import VueRouter from 'vue-router'


      Vue.use(VueRouter);

      const router = new VueRouter({routes: Routes, mode: 'history'});

      const app = new Vue({
      el: '#root',
      render: h => h(SFC),
      router: router
      });


      I have 3 routes ('/', '/about', '/contact') inside routes file..
      Nothing works with beforeRouteUpdate or Leave, but just if I add watcher for $route it does work...



      Like this:



      watch: {
      $route(to, from) {
      console.log('after', this.$route.path);
      }
      }


      But this fires after route is loaded, I need one before it leaves current route and one after it load next route.



      Any help?







      vue.js vuejs2 vue-component vue-router






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 10 at 23:32

























      asked Nov 10 at 23:22









      Learner

      55112




      55112
























          2 Answers
          2






          active

          oldest

          votes


















          0














          It works as expected.



          Referring to vue-router documentation about In-Component Navigation Guards:




          called before the route that renders this component is confirmed.




          Meaning, that when navigation guards are declared inside component, they will be triggered only when render of that component happens. Not nested components, as in code example above, because SFC.vue is never unmounted.



          You can achieve desired behavior by:





          1. watch-ing route changes from parent component, as in example code you provided. The downside is that it will be triggered on any(!) route change. If navigation occurs inside nested components - it will be triggered. The benefit - this approach has access to component instance (this).

          2. With Global Guards declared on router instance. Again, it will be triggered on every route change, so you will have to verify if it is a child route of those you should handle.

          3. By declaring a handler function and adding it to each route configuration as in code example. Good thing is that you can reuse handler functions and keep them in a separate module, while importing inside router instance constructor.

          4. Move existing handlers into a mixin and using it inside component declaration of each route that should be handled.






          share|improve this answer





















          • How can I access refs from vue instance component within global guards, I keep getting undefined...
            – Learner
            Nov 11 at 1:45










          • You can't. Global router guards do not receive component's instance as arguments, only Route object. Only way to access $refs is inside component and only after mounted hook.
            – aBiscuit
            Nov 11 at 2:14








          • 1




            I found out that I can use this.$router. from component for done and maybe i can start by adding native click event to route link, i am dead now will try after few hours of sleep
            – Learner
            Nov 11 at 2:27






          • 1




            I found better answer :D Which works :D
            – Learner
            Nov 11 at 11:40



















          0














          After good sleep I found answer:



          I made:



          window.Event = new class {
          constructor() {
          this.vue = new Vue();
          }

          fire(event, data = null) {
          this.vue.$emit(event, data);
          }

          listen(event, callback) {
          this.vue.$on(event, callback);
          }
          };

          const router = new VueRouter({routes: Routes, mode: 'history'});

          router.beforeEach((to, from, next) => {
          Event.fire('loader-start', 'start');
          next();
          });

          router.afterEach((to, from) => {
          setTimeout(function() {
          Event.fire('loader-done', 'done');
          }, 500);
          });


          And inside component I listen for those events and change the $ref :D






          share|improve this answer





















            Your Answer






            StackExchange.ifUsing("editor", function () {
            StackExchange.using("externalEditor", function () {
            StackExchange.using("snippets", function () {
            StackExchange.snippets.init();
            });
            });
            }, "code-snippets");

            StackExchange.ready(function() {
            var channelOptions = {
            tags: "".split(" "),
            id: "1"
            };
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function() {
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled) {
            StackExchange.using("snippets", function() {
            createEditor();
            });
            }
            else {
            createEditor();
            }
            });

            function createEditor() {
            StackExchange.prepareEditor({
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            });


            }
            });














            draft saved

            draft discarded


















            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53244391%2fbeforerouteupdate-or-leave-does-not-react-in-single-file-component%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            2 Answers
            2






            active

            oldest

            votes








            2 Answers
            2






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            0














            It works as expected.



            Referring to vue-router documentation about In-Component Navigation Guards:




            called before the route that renders this component is confirmed.




            Meaning, that when navigation guards are declared inside component, they will be triggered only when render of that component happens. Not nested components, as in code example above, because SFC.vue is never unmounted.



            You can achieve desired behavior by:





            1. watch-ing route changes from parent component, as in example code you provided. The downside is that it will be triggered on any(!) route change. If navigation occurs inside nested components - it will be triggered. The benefit - this approach has access to component instance (this).

            2. With Global Guards declared on router instance. Again, it will be triggered on every route change, so you will have to verify if it is a child route of those you should handle.

            3. By declaring a handler function and adding it to each route configuration as in code example. Good thing is that you can reuse handler functions and keep them in a separate module, while importing inside router instance constructor.

            4. Move existing handlers into a mixin and using it inside component declaration of each route that should be handled.






            share|improve this answer





















            • How can I access refs from vue instance component within global guards, I keep getting undefined...
              – Learner
              Nov 11 at 1:45










            • You can't. Global router guards do not receive component's instance as arguments, only Route object. Only way to access $refs is inside component and only after mounted hook.
              – aBiscuit
              Nov 11 at 2:14








            • 1




              I found out that I can use this.$router. from component for done and maybe i can start by adding native click event to route link, i am dead now will try after few hours of sleep
              – Learner
              Nov 11 at 2:27






            • 1




              I found better answer :D Which works :D
              – Learner
              Nov 11 at 11:40
















            0














            It works as expected.



            Referring to vue-router documentation about In-Component Navigation Guards:




            called before the route that renders this component is confirmed.




            Meaning, that when navigation guards are declared inside component, they will be triggered only when render of that component happens. Not nested components, as in code example above, because SFC.vue is never unmounted.



            You can achieve desired behavior by:





            1. watch-ing route changes from parent component, as in example code you provided. The downside is that it will be triggered on any(!) route change. If navigation occurs inside nested components - it will be triggered. The benefit - this approach has access to component instance (this).

            2. With Global Guards declared on router instance. Again, it will be triggered on every route change, so you will have to verify if it is a child route of those you should handle.

            3. By declaring a handler function and adding it to each route configuration as in code example. Good thing is that you can reuse handler functions and keep them in a separate module, while importing inside router instance constructor.

            4. Move existing handlers into a mixin and using it inside component declaration of each route that should be handled.






            share|improve this answer





















            • How can I access refs from vue instance component within global guards, I keep getting undefined...
              – Learner
              Nov 11 at 1:45










            • You can't. Global router guards do not receive component's instance as arguments, only Route object. Only way to access $refs is inside component and only after mounted hook.
              – aBiscuit
              Nov 11 at 2:14








            • 1




              I found out that I can use this.$router. from component for done and maybe i can start by adding native click event to route link, i am dead now will try after few hours of sleep
              – Learner
              Nov 11 at 2:27






            • 1




              I found better answer :D Which works :D
              – Learner
              Nov 11 at 11:40














            0












            0








            0






            It works as expected.



            Referring to vue-router documentation about In-Component Navigation Guards:




            called before the route that renders this component is confirmed.




            Meaning, that when navigation guards are declared inside component, they will be triggered only when render of that component happens. Not nested components, as in code example above, because SFC.vue is never unmounted.



            You can achieve desired behavior by:





            1. watch-ing route changes from parent component, as in example code you provided. The downside is that it will be triggered on any(!) route change. If navigation occurs inside nested components - it will be triggered. The benefit - this approach has access to component instance (this).

            2. With Global Guards declared on router instance. Again, it will be triggered on every route change, so you will have to verify if it is a child route of those you should handle.

            3. By declaring a handler function and adding it to each route configuration as in code example. Good thing is that you can reuse handler functions and keep them in a separate module, while importing inside router instance constructor.

            4. Move existing handlers into a mixin and using it inside component declaration of each route that should be handled.






            share|improve this answer












            It works as expected.



            Referring to vue-router documentation about In-Component Navigation Guards:




            called before the route that renders this component is confirmed.




            Meaning, that when navigation guards are declared inside component, they will be triggered only when render of that component happens. Not nested components, as in code example above, because SFC.vue is never unmounted.



            You can achieve desired behavior by:





            1. watch-ing route changes from parent component, as in example code you provided. The downside is that it will be triggered on any(!) route change. If navigation occurs inside nested components - it will be triggered. The benefit - this approach has access to component instance (this).

            2. With Global Guards declared on router instance. Again, it will be triggered on every route change, so you will have to verify if it is a child route of those you should handle.

            3. By declaring a handler function and adding it to each route configuration as in code example. Good thing is that you can reuse handler functions and keep them in a separate module, while importing inside router instance constructor.

            4. Move existing handlers into a mixin and using it inside component declaration of each route that should be handled.







            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Nov 11 at 1:38









            aBiscuit

            1,3811613




            1,3811613












            • How can I access refs from vue instance component within global guards, I keep getting undefined...
              – Learner
              Nov 11 at 1:45










            • You can't. Global router guards do not receive component's instance as arguments, only Route object. Only way to access $refs is inside component and only after mounted hook.
              – aBiscuit
              Nov 11 at 2:14








            • 1




              I found out that I can use this.$router. from component for done and maybe i can start by adding native click event to route link, i am dead now will try after few hours of sleep
              – Learner
              Nov 11 at 2:27






            • 1




              I found better answer :D Which works :D
              – Learner
              Nov 11 at 11:40


















            • How can I access refs from vue instance component within global guards, I keep getting undefined...
              – Learner
              Nov 11 at 1:45










            • You can't. Global router guards do not receive component's instance as arguments, only Route object. Only way to access $refs is inside component and only after mounted hook.
              – aBiscuit
              Nov 11 at 2:14








            • 1




              I found out that I can use this.$router. from component for done and maybe i can start by adding native click event to route link, i am dead now will try after few hours of sleep
              – Learner
              Nov 11 at 2:27






            • 1




              I found better answer :D Which works :D
              – Learner
              Nov 11 at 11:40
















            How can I access refs from vue instance component within global guards, I keep getting undefined...
            – Learner
            Nov 11 at 1:45




            How can I access refs from vue instance component within global guards, I keep getting undefined...
            – Learner
            Nov 11 at 1:45












            You can't. Global router guards do not receive component's instance as arguments, only Route object. Only way to access $refs is inside component and only after mounted hook.
            – aBiscuit
            Nov 11 at 2:14






            You can't. Global router guards do not receive component's instance as arguments, only Route object. Only way to access $refs is inside component and only after mounted hook.
            – aBiscuit
            Nov 11 at 2:14






            1




            1




            I found out that I can use this.$router. from component for done and maybe i can start by adding native click event to route link, i am dead now will try after few hours of sleep
            – Learner
            Nov 11 at 2:27




            I found out that I can use this.$router. from component for done and maybe i can start by adding native click event to route link, i am dead now will try after few hours of sleep
            – Learner
            Nov 11 at 2:27




            1




            1




            I found better answer :D Which works :D
            – Learner
            Nov 11 at 11:40




            I found better answer :D Which works :D
            – Learner
            Nov 11 at 11:40













            0














            After good sleep I found answer:



            I made:



            window.Event = new class {
            constructor() {
            this.vue = new Vue();
            }

            fire(event, data = null) {
            this.vue.$emit(event, data);
            }

            listen(event, callback) {
            this.vue.$on(event, callback);
            }
            };

            const router = new VueRouter({routes: Routes, mode: 'history'});

            router.beforeEach((to, from, next) => {
            Event.fire('loader-start', 'start');
            next();
            });

            router.afterEach((to, from) => {
            setTimeout(function() {
            Event.fire('loader-done', 'done');
            }, 500);
            });


            And inside component I listen for those events and change the $ref :D






            share|improve this answer


























              0














              After good sleep I found answer:



              I made:



              window.Event = new class {
              constructor() {
              this.vue = new Vue();
              }

              fire(event, data = null) {
              this.vue.$emit(event, data);
              }

              listen(event, callback) {
              this.vue.$on(event, callback);
              }
              };

              const router = new VueRouter({routes: Routes, mode: 'history'});

              router.beforeEach((to, from, next) => {
              Event.fire('loader-start', 'start');
              next();
              });

              router.afterEach((to, from) => {
              setTimeout(function() {
              Event.fire('loader-done', 'done');
              }, 500);
              });


              And inside component I listen for those events and change the $ref :D






              share|improve this answer
























                0












                0








                0






                After good sleep I found answer:



                I made:



                window.Event = new class {
                constructor() {
                this.vue = new Vue();
                }

                fire(event, data = null) {
                this.vue.$emit(event, data);
                }

                listen(event, callback) {
                this.vue.$on(event, callback);
                }
                };

                const router = new VueRouter({routes: Routes, mode: 'history'});

                router.beforeEach((to, from, next) => {
                Event.fire('loader-start', 'start');
                next();
                });

                router.afterEach((to, from) => {
                setTimeout(function() {
                Event.fire('loader-done', 'done');
                }, 500);
                });


                And inside component I listen for those events and change the $ref :D






                share|improve this answer












                After good sleep I found answer:



                I made:



                window.Event = new class {
                constructor() {
                this.vue = new Vue();
                }

                fire(event, data = null) {
                this.vue.$emit(event, data);
                }

                listen(event, callback) {
                this.vue.$on(event, callback);
                }
                };

                const router = new VueRouter({routes: Routes, mode: 'history'});

                router.beforeEach((to, from, next) => {
                Event.fire('loader-start', 'start');
                next();
                });

                router.afterEach((to, from) => {
                setTimeout(function() {
                Event.fire('loader-done', 'done');
                }, 500);
                });


                And inside component I listen for those events and change the $ref :D







                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Nov 11 at 11:42









                Learner

                55112




                55112






























                    draft saved

                    draft discarded




















































                    Thanks for contributing an answer to Stack Overflow!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    To learn more, see our tips on writing great answers.





                    Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                    Please pay close attention to the following guidance:


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53244391%2fbeforerouteupdate-or-leave-does-not-react-in-single-file-component%23new-answer', 'question_page');
                    }
                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    這個網誌中的熱門文章

                    Hercules Kyvelos

                    Tangent Lines Diagram Along Smooth Curve

                    Yusuf al-Mu'taman ibn Hud