Vue Router beforeRouteLeave不会停止子组件

Oğu*_*tel 8 vue.js vue-router vuejs2

我有一个简单的问题.我只想在路线改变时取消子组件.这是一个例子.有一个家庭组件是父母.它有一个子组件.我只想在安装的子组件中更改路径时停止间隔功能

import Home from "./components/Home.vue";
import Another from "./components/Another.vue";
const routes = [
    { path: '', component: Home },
    { path: '/another', component: Another }
];
const router = new VueRouter({
    routes
});
const app = new Vue({
    router

}).$mount('#app');
Run Code Online (Sandbox Code Playgroud)

这是家庭组件.Home.vue

<template>
  <sub-component></sub-component>
</template>
<script type="text/babel">
    import SubComponent from "./components/Subcomponent.vue";
    export default {
       components:{
          'sub-component':SubComponent
       }
    }
</script>
Run Code Online (Sandbox Code Playgroud)

这是子组件.Subcomponent.vue

<template>
   <div> Sub component will run a interval </div>
</template>
<script type="text/babel">
    import SubComponent from "./components/Subcomponent.vue";
    export default {
       components:{
          'sub-component':SubComponent
       },
       mounted:function(){
           setInterval(function(){
             console.log("I should cancel when route changed");
           },1000)
       }
    }
</script>
Run Code Online (Sandbox Code Playgroud)

我尝试过beforeRouteLeave方法,但它只停止Home.vue方法.

Man*_*ani 13

当您使用子组件(在路径组件内)时,您将无法beforeRouteLeave直接使用.

您的子组件是路径的子组件.因此,您需要使用子组件引用从路径组件触发子组件的exit方法,如下面的指南页所述:

https://vuejs.org/v2/guide/components.html#Child-Component-Refs

您可以按如下方式创建对子组件的引用:

<sub-component ref="mySubComponent"></sub-component>
Run Code Online (Sandbox Code Playgroud)

现在在您的路线组件中,您可以执行以下操作:

beforeRouteLeave: function(to, from, next) {
    // Indicate to the SubComponent that we are leaving the route
    this.$refs.mySubComponent.prepareToExit();
    // Make sure to always call the next function, otherwise the hook will never be resolved
    // Ref: https://router.vuejs.org/en/advanced/navigation-guards.html
    next();
}
Run Code Online (Sandbox Code Playgroud)

注意:您的路由组件调用prepareToExit()此示例中调用的子子组件中的方法,您可以在其中执行清理,如下所示:

methods: {
    prepareToExit: function() {
        console.log("Preparing to exit sub component, stopping 'twoSecondsTimerEvents'")
        clearInterval(this.twoSecondsTimerEvents)
    }
}
Run Code Online (Sandbox Code Playgroud)

这是一个工作示例:https://jsfiddle.net/mani04/crwuxez3/(控制台中记录的所有详细信息)

请注意:此示例使用Vue 2.1.10和Vue-Router 2.2.0(截至今天的最新版本).以前的版本中存在一些问题,围绕导航卫兵功能,现在已完全解决.

编辑:替代方法

在发布上述解决方案后,我意识到有一种更简单的方法可以做到这一点.您的子组件可能无法获得特定于路由的回调beforeRouteLeave,但它仍然是遵循组件生命周期的Vue组件.

因此,基于组件生命周期图,您将beforeDestroy在子组件中具有可用于清除计时器的回调.

以下是如何做到这一点:

const SubComponent = Vue.component('sub-component', {
    template: `...`,
    data: function() {...},
    mounted: function() {...},
    // 'prepareToExit' method not required here
    // And also there is no need to handle 'beforeRouteLeave' in parent
    beforeDestroy: function() {
        console.log("Stopping the interval timer")
        clearInterval(this.twoSecondsTimerEvents)
    }
});
Run Code Online (Sandbox Code Playgroud)

好处:

  1. 比早期的方法简单得多.
  2. 无需处理父组件中的任何子组件引用.
  3. 无需从父组件触发清理方法.

没有缺点,但是此触发器与路径更改并不完全相关,因此您希望根据目标路由执行任何其他操作.如果你更喜欢这个,你也可以使用它.