我有一个简单的问题.我只想在路由改变时取消子组件.这是一个样本.有一个主组件是父组件.它有一个子组件.我只想在子组件中的路由发生变化时停止间隔功能

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

这是主组件.家vue

<template>
  <sub-component></sub-component>
</template>
<script type="text/babel">
    import SubComponent from "./components/Subcomponent.vue";
    export default {
       components:{
          'sub-component':SubComponent
       }
    }
</script>

这是子组件.子组件.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>

我try 了BeforeRouteleve方法,但它只在家里停止.vue方法.

推荐答案

由于使用的是子组件(在管线组件内部),因此无法直接使用beforeRouteLeave.

您的子组件是路由的child component.因此,您需要使用Child Component Refs从路由组件触发子组件的退出方法,如下指南页面所述:

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

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

<sub-component ref="mySubComponent"></sub-component>

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

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

注意:在本例中,路由组件调用名为prepareToExit()的子组件中的一个方法,在该子组件中,您可以按如下方式进行清理:

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

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

请注意:此示例使用Vue 2.1.10和Vue Router 2.2.0(截至今天的最新版本).以前的版本中有一些问题,大约有Navigation Guards个功能,现在已经完全解决了.

EDIT: Alternate method

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

因此,基于component lifecycle diagram,子组件中有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)
    }
});

优势:

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

没有缺点,但是这个触发器并不完全与路由更改相关联,以防您想根据目的地路由执行任何其他操作.如果你更喜欢这个,你也可以用它.

Vue.js相关问答推荐

Nuxt3 / Vue3 - 当属性更改时如何动态更改渲染组件?

Vue.js 3 没有组件的实例?

为什么将 name 与 router-link 一起使用比仅使用 to 与 path 更好?

Nuxt3-Vue中的useRoute和useRouter有什么区别

在 Ajax 函数中访问 Vue.js 组件属性

如何在 vue 的 scss 中使用深度 Select 器

如何只查看数组中的一个对象?

在 Vue 中,如何使用 npm run build 将 .htaccess 包含到生产环境中?

在 vue 组件中检索配置和环境变量

vuejs中watch方法和计算方法有什么区别

为 Vue 组件动态添加属性

Vuex 存储数据总是驻留在内存中?

Vue3在按钮单击时以编程方式创建组件实例

如何从 keep-alive 中销毁缓存的 Vue 组件?

将登录页面包含在单页应用程序中是否不安全?

在 VueJS 中观察元素的高度

更改时(change)调用函数

从 vuex 存储访问 $vuetify 实例属性

Vuetify 离线文档

Apollo 客户端在向服务器发送Mutations 时返回400(错误请求)错误