问题如标题。
我搜索,大部分资料是 路由 A 中有个定时器,不是在 component 里。我现在的问题是 如何获取到 component 中 timer = setTimeout() 的这个 timer。
只找到 点击这里,是把 timer 写成全局的了,所以方便访问。不知道这样好不好,有其他方法吗?
示例代码:
Vue.component('v-osd', { template: 'xxx', data: function() { var myData = {}; function refresh() { get( 'get_client_osd_list', { id: 1, }, respOnse=> { refreshTimer = setTimeout(function() { refresh(); }, 500); } ); } refresh(); return myData; }, }); var routeA = { template: 'yyy', data: function() { return {}; }, beforeRouteLeave(to, from, next) { // 如何获取到 组件里面的 timer?? clearInterval(refreshTimer); next(); }, };
发现在 ajax 的 response 里 setTimeout,在 clearTimeout 时,会有其他问题。为了避免问题偏移,去掉ajax,新的示例如下: 参考 wiluxy,在组件的 beforeDestroy 中清除
<script src="https://cdn.jsdelivr.net/npm/[email protected]"></script> <script src="https://unpkg.com/[email protected]/dist/vue-router.js"></script> <div id="app"> <router-link to='/routea'>go to a</router-link> <router-link to='/routeb'>go to b</router-link> <router-view></router-view> </div> <!-- component --> <template id='templateOsd'> <div>component osd</div> </template> <template id="templatea"> <div>route a</div> </template> <template id="templateb"> <div> <div>route b</div> <v-osd></v-osd> </div> </template> <script src="index.js"></script>
Vue.component('v-osd', { template: '#templateOsd', data: function () { var myData = { refreshTimer: -1, }; var self = this; function refreshOsd() { console.log('refreshOsd in'); self.refreshTimer = setTimeout(refreshOsd, 2000); } refreshOsd(); return myData; }, beforeDestroy: function () { console.log('v-osd beforeDestory'); clearTimeout(this.refreshTimer) }, destroyed: function () { console.log('v-osd destroyed'); } }); // 路由a var compOnenta= { template: '#templatea', data: function () { var data = {}; return data; }, }; // 路由b var compOnentb= { template: '#templateb', data: function () { var data = {}; return data; }, }; var router = new VueRouter({ routes: [{ name: "a", path: "/routea", component: componenta }, { name: "b", path: "/routeb", component: componentb } ] }) var app = new Vue({ router, data: {}, }) app.$mount('#app');
![]() | 1 wiluxy 2019-10-10 19:44:43 +08:00 跳转到另外一个路由的话,如果当前路由没有倍<keep-active>保留的话,component 应该就跟着销毁了,调用组件销毁前生命周期清除定时器,或者用 vue-router 的路由跳转钩子函数。。。跳转前判断当前路由是不是路由 A,是的话就清除定时器 |
2 15651980765 2019-10-11 09:52:16 +08:00 这个组件没有 keepalive 缓存的话,beforeDestroy 的时候清除这个定时器; 这个组件有 keepalive 缓存的话,deactivated 的时候清除这个定时器。 个人观点,如有错误请指正。 楼上通过路由跳转钩子函数判断当前路由的方法好像也可以,但是定时器应该得放在全局变量里。 |
![]() | 3 jiushengyuan OP 感谢 @wiluxy @15651980765 提供的, 现在在 component beforeDestroy 中,引用 refreshTimer,就不用设成全局变量了。 有个新问题,路由是没有 keepalive 的,如果我不清除定时器,在跳转到新路由时,refreshOsd 还是会不断执行,也可以访问到其中的 self 是个 compoenent。 可是 component 不是已经被销毁了吗? |
![]() | 4 jiushengyuan OP 是给的代码示例太长,大家都没耐心看了么。其实那个只是方便模拟贴出来,问题不复杂的。 新问题:路由是没有 keepalive 的,如果我不清除定时器,在跳转到新路由时,refreshOsd 还是会不断执行,也可以访问到其中的 self 是个 compoenent。 可是 component 不是已经被销毁了吗? 有没有大佬帮忙看看呀 |