vue使用keep-alive后是不是watch事件不会被销毁

我发现项目使用了keep-alive动态缓存页面之后,有一些很难解决的问题
ps: 我这里不是用keep-alive全部都缓存,而是动态缓存,就是使用了:exclude 配合route.meta 来动态缓存一些页面,比如从按钮点击进入时就是没有缓存的页面,点击浏览器前进后退时,进入的就是被缓存的页面

1.每个页面里面设置的watch监听事件,如果监听了路由的变化或者vuex的变化,好像在切换页面的时候不会被销毁

比如在watch里面监听vuex某个值变化时,写了一个请求数据的方法,切换到另一页,居然还会发起那个请求。

watch: {
    '$store.state.common.isRefreshLoading'(val) {
      if(val) {
        this.getData();
      }
    }
}

我必须这样写才可以保证它不会切换到别的页面还会被触发:

watch: {
    '$store.state.common.isRefreshLoading'(val) {
      if(val && this.$route.name === 'Home') {
        this.getData();
      }
    }
}

2.页面上的一些方法会被叠加触发,不知道是不是监听了路由的原因,导致每次切换页面,很多方法会被重复叠加的触发,比如切换第一次触发2次,切换第2次触发3次,第3次触发4次,类似这样的情况

有没有大佬可以帮忙解答一下这个困扰了我很久的问题,万分感谢

阅读 12.2k
2 个回答

Vue 实例是一个 JavaScript 对象,其一旦创建就会有相应的生命周期,其中的 watchers 在该对象存续期内都会生效,直到 destroy 时被 teardown:

clipboard.png

keep-alive 会将 Vue 实例始终保持在内存中,因此该 Vue 实例始终存续,相应的 watchers 始终生效。
你可以在组件中添加 beforeDestroy hook,验证一下 keep-alive 的 component 有没有被 destroy。

你问题中的处理中添加了对 route.name 的判断可以解决路由切换出去之后重复触发的问题,你还可以设置一个 activatedFlag Vue 实例数据,然后在 activated and deactivated lifecycle hooks 里对此 flag 进行切换,并在 watchers 里使用这个 flag 进行判断,决定是否需要触发请求。

{
  data () {
    return {
      activatedFlag: false
    };
  },
  watch: {
    '$store.state.common.isRefreshLoading'(val) {
      if(val && this.activatedFlag) {
        this.getData();
      }
    }
  },
  activated () {
    this.activatedFlag = true;
  },
  deactivated () {
    this.activatedFlag = false;
  }
}

上述代码中的 data 和 两个 hooks 可以写成一个全局 mixin,减少重复代码。

应该就是watch的问题了,切换页面都会触发到缓存的页面方法,在离开页面的时候取消监听就可以了。
deactivated中添加unwatch
https://cn.vuejs.org/v2/api/#vm-watch

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题