BeforeRouteUpdate或Leave在单个文件组件中不起作用

时间:2018-11-10 23:22:13

标签: vue.js vuejs2 vue-component vue-router

<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添加了监视程序,它也能起作用...

赞:

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

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

有帮助吗?

2 个答案:

答案 0 :(得分:0)

它按预期工作。

请参考vue-router关于In-Component Navigation Guards的文档:

  在确定呈现此组件的路径之前调用

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

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

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

答案 1 :(得分:0)

睡眠良好后,我找到了答案:

我做了:

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