vue 由 clearTimeout无法清除定时器引发的vue 周期函数,事件代码执行顺序思考

最近做个移动的项目,遇到需求:首页无操作20秒,自动退出登录。其他页面20秒无操作,自动跳转首页。

所谓的无操作,包括点击,触摸,滑动等用户行为。
这需求其实也很简单,思路就是使用定时器setTimeout设定时间,监听页面是否有点击,触摸,滑动等事件在操作,如果没有,则时间一到,就跳转首页或者退出登录,如果有事件发生,则清除定时器,然后重启定时器

那我们先来实现下这个逻辑,先放首页试试

<template><div class="home" @click="screenClick" @touchmove="touchmove" @touchstart="touchStart" @touchend="touchEnd"><div class="home-img-box"></div><div class="login-box row-center"><strong class="login-text">轻触屏幕,继续操作</strong></div></div>
</template>
<script>
export default {created() {this.screenClick()},methods:{/*** 屏幕在点击*/screenClick(){// console.log('屏幕点击')this.delayUserHandle()},/*** 延迟*/delayUserHandle(){window.clearTimeout(this.timeOut)// console.log('开始延迟')// console.log(this.timeOut)this.timeOut = window.setTimeout(()=> {// console.log('延迟结束')const {name} = this.$routeif(name==='Home'){// 首页,this.$store.dispatch('logout')}else{this.$store.dispatch('logout')this.$router.replace('/')}},20000)},/*** 触摸开始*/touchStart(){window.clearTimeout(this.timeOut)},/*** 触摸滑动*/touchmove(){window.clearTimeout(this.timeOut)},/*** 触摸结束*/touchEnd(e){// console.log('touchEnd')// console.log(e)this.delayUserHandle()}},
}
</script>

ok,这个就已经实现了一个页面的20秒无操作退出。
但是我们需要的是任意页面,而不是一个,所以,这一块有很多公用的地方。所以我们可以将公共的部分抽出来,这里使用mixins 混入。
新建 clear-login-info.js文件,这里放在src下的mixins文件夹中,同时,我们得在页面离开,销毁后,将定时器销毁。可以销毁定时器的地方有beforeDestroy,destroyed,beforeRouteLeave。开始的时候,没考虑那么多,直接用beforeRouteLeave,就是页面离开前的路由守卫。
clear-login-info.js 代码如下:

//清除用户信息
import {mapState} from "vuex";export default {data(){return{timeOut:null,//定时器}},computed:{...mapState(['hasLogin'])},created() {this.timeOut = setTimeout(()=>{this.$store.dispatch('clearInfo')},30000)this.screenClick()},methods:{/*** 屏幕在点击*/screenClick(){this.delayUserHandle()},/*** 延迟*/delayUserHandle(){window.clearTimeout(this.timeOut)// console.log('开始延迟')// console.log(this.timeOut)this.timeOut = window.setTimeout(()=> {// console.log('延迟结束')const {name} = this.$routeif(name==='Home'){// 首页,this.$store.dispatch('logout')}else{this.$store.dispatch('logout')this.$router.replace('/')}},20000)},/*** 触摸开始*/touchStart(){clearTimeout(this.timeOut)},/*** 触摸滑动*/touchmove(){clearTimeout(this.timeOut)},/*** 触摸结束*/touchEnd(){this.delayUserHandle()}},beforeRouteLeave(to,from,next){clearTimeout(this.timeOut)next()}
}

这就完了吗?的确是达到效果了,但是,仅仅如此也就没有本文了。有Bug.
使用后发现,从首页跳到其他页面后,不管是否有操作,20秒后都会跳转到首页。而且没有使用该效果的页面也会跳转到首页。
这里有个需要注意的地方就是,定时器并不会在页面销毁后自动消除。需要手动清除定时器。但是这里已经在beforeRouteLeave里面写了。那么原因就只要一个,真正起作用的定时器并没有被清除!

前面说过页面离开前可以清除定时器的有三个地方,beforeDestroy,destroyed和beforeRouteLeave,那么如果是跳转下一页面前,定时器没有消除成功,那我们就尽量在最后的时机来触发试试。首先destroyed肯定在beforeDestroy之后触发,所以我们需要比较下destroyed和beforeRouteLeave到底谁最后触发。验证方式也很简单,直接console.log打印即可。
首先在app.vue弄个路由跳转,这里假设有两个页面 首页和关于

<template>
<div><router-link to="/mkf">关于</router-link><router-link to="/home">首页</router-link><router-view></router-view>
</div>
</template>

然后我们在首页来检测打印

<!--Home-->
<template><div>Home</div>
</template>
<script>
export default {destroyed() {console.log('页面销毁')},beforeRouteLeave(to,from,next){console.log('路由守卫beforeRouteLeave')next()}
}
</script>

运行项目,在首页点击 跳转到 "关于"页面,看看浏览器打印结果

结果是destroyed最后执行。好,那我们吧清除定时器放在destroyed里面,将clear-login-info.js的beforeRouteLeave替换为destroyed

  destroyed() {// console.log('销毁')window.clearTimeout(this.timeOut)},

继续测试,我们发现,定时器依然没有被清除。
因为destroyed执行的时候,页面其实已经切换到新页面了。这时候去清楚上页面的定时器,变量可能已经不存在,所以没有清除成功。

这个问题比较烦,就不再继续测试了。总之不能在destroyd清除定时器,这方案不得行,这样使用会发现,定时器经常没有被清除掉。

思考了一下,这个需求,使用定时器加vuex即可解决。

vue 由 clearTimeout无法清除定时器引发的vue 周期函数,事件代码执行顺序思考相关推荐

  1. vue中父子组件先后渲染_vue父子组件钩子函数的执行顺序

    加载渲染过程 父beforeCreate->父created->父beforeMount->子beforeCreate->子created->子beforeMount-& ...

  2. vue中定时器一般用法,定时器函数传参以及清除定时器

    一.vue中定时器一般用法(举个例子) 显示当前时间, setInterval()方法会每秒执行一次函数,类似手表功能: <template><div class="use ...

  3. JS设置定时器和清除定时器

    最近在项目中频繁运用到js定时器,现在和大家分享一下方法.在前端开发的过程中,有些时候需要某段程序等待一段时间后再开始执行,在JavaScript中主要通过定时器实现这一类需求. JS的两种定时器 w ...

  4. 1. Vue从入门到精通(第一章 vue核心)

    Vue从入门到精通(第一章 vue核心) 第一章 Vue核心 1. Vue简介 1.1 Vue是什么? 1.2 Vue的作者以及迭代版本 1.3 Vue的特点 2. 搭建Vue开发环境 2.1 安装V ...

  5. 什么是Vue生命周期?Vue生命周期的作用是什么?vue八种钩子函数

    1.vue生命周期介绍 vue生命周期是指vue对象从创建到销毁的过程.也就是vue对象从开始创建.初始化数据.编译模板.挂载Dom.渲染→更新→渲染.卸载这一系列过程. 其作用是在vue生命周期的不 ...

  6. vue优雅的清除定时器

    今日跟朋友交流,偶然间被问到这个问题:"在vue的生命周期中定义一个定时器,如何在destoryed钩子中不手动卸载的操作下,自动卸载定时器" 引发了一些思考,也总结出一些之前未接 ...

  7. 清除定时器 和 vue 中遇到的定时器setTimeout setInterval问题

    2019-03更新 找到了更简单的方法,以setinterval为例,各位自行参考 mounted() {const that = thisconst timer = setInterval(func ...

  8. 关于vue中如何清除定时器的方法

    一.问题 1.在vue中使用setTimeout定时器的时候,可能会遇到关不掉的情况,会存在明明已经在beforeDestroy和destroyed中设置了定时器清除了,但是有时候没生效,定时器还会继 ...

  9. vue中clearInterval()清除定时器报timeout.close is not a function错误?

    在vue中实现播放音乐时旋转光碟的功能时候使用到了定时器,在暂停播放音乐的时候清除定时器,但是发现报了一个奇怪的错误: 在网上查了一下,发现报错的原因好像是vue中有自己内置的clearInterva ...

最新文章

  1. 简明python教程在线-Python简明教程
  2. 基于redis分布式锁实现的多线程并发程序(原创)
  3. 伯努利数(详解 + 例题 :P3711 仓鼠的数学题)
  4. c语言程序设计徐立辉答案,C语言程序设计 牛志成,徐立辉,刘冬莉著 清华大学出版社 9787302165620...
  5. 2011年值得注意的5个设计趋势
  6. 后缀表达式的值(信息学奥赛一本通-T1331)
  7. BERT模型实战之多文本分类(附源码)
  8. vue 打包后本地先自己启动服务 anywhere 非常好用
  9. 本周小结!(回溯算法系列三)
  10. spark学习——(一)spark简介
  11. storm1.x支持主节点nimbus高可用 多master集群部署
  12. 易筋SpringBoot 2.1 | 第八篇:Mybatis访问MySQL
  13. 通过JDBC连接Oracle数据库中的十大技巧
  14. 计算机fn的作用,必看干货!笔记本电脑fn键的作用
  15. 排水管网信息系统、市政排水管网信息化智慧化管理
  16. PR标题动画模板 创意动态多行标题注释字幕条pr模板
  17. Win10取消应用商店版的Python
  18. 数独 ( 三 ) ——解数独
  19. mac brew 测速 软件_最好用的网络测速工具speedtest
  20. 【图像相关】图像质量评价指标 PSNR 和 SSIM

热门文章

  1. 一致性(Consistency)介绍
  2. windows server 2016系统普通用户具有绝大多数最高权限的设置方法
  3. C#之基础4---①什么是命名空间,为什么要使用命名空间,命名空间与类的区别
  4. CentOS8配置RAID0、RAID1
  5. 【R】生成聊天记录词云
  6. flutter解析本地json数组
  7. PermitRootLogin yes无效问题
  8. 【转】人眼视觉系统HVS
  9. 13-Set Time Zone
  10. 超宽屏显示器32寸,双11电竞游戏显示器的最佳选择