代码之家  ›  专栏  ›  技术社区  ›  Learner

BeforeRouteUpdate或Leave在单个文件组件中不响应

  •  1
  • Learner  · 技术社区  · 6 年前
    <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>
    

    这是在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
    });
    

    我在路由文件中有3个路由(“/”,“/about”,“/contact”)。 对beforerouteupdate或leave不起任何作用,但只要我为$route添加了watcher,它就会起作用…

    这样地:

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

    但这会在路由加载之后触发,我需要在它离开当前路由之前和在它加载下一个路由之后都有一个。

    有什么帮助吗?

    2 回复  |  直到 6 年前
        1
  •  0
  •   aBiscuit    6 年前

    它按预期工作。

    vue-router 有关的文档 In-Component Navigation Guards :

    在确认呈现此组件的路由之前调用。

    也就是说,当导航保护在组件内部声明时,只有在该组件的呈现发生时才会触发它们。不是嵌套组件,如上面的代码示例所示,因为 SFC.vue 从不卸载。

    您可以通过以下方式实现所需的行为:

    1. watch -从父组件更改路由,如您提供的示例代码中所示。缺点是它会在任何一个(!)上触发。路线变更。如果导航发生在嵌套组件中,则会触发导航。好处-此方法可以访问组件实例( this )
    2. Global Guards 在路由器实例上声明。同样,它将在每次路由更改时触发,因此您必须验证它是否是您应该处理的那些路由的子路由。
    3. 通过声明一个处理程序函数并将其添加到每个路由配置中 code example 。好的是,您可以重用处理程序函数,并将它们保存在单独的模块中,同时将它们导入到路由器实例构造函数中。
    4. 将现有处理程序移入 mixin 并在每个应该处理的路由的组件声明中使用它。
        2
  •  0
  •   Learner    6 年前

    睡得好之后,我找到了答案:

    我做了:

    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);
    });
    

    在组件内部,我监听这些事件并更改$ref:d