vue用户长时间不操作退出到登录页的两种实现方式

目录
  • 问题描述
  • 前端控制(方式一)
    • 思路
    • 代码
  • 后端控制(方式二)
    • 思路
    • 代码
  • 总结

问题描述

产品说,出于安全考虑,用户长时间不操作,就回到登录页面,让用户重新登录,就像银行的app一样。本文就记录一下实现这种效果的两种方式,分别是前端控制和后端控制,各有细节及适用使用场景

前端控制(方式一)

思路

首先,用户长时间不操作具体表现形式是啥?其实就是事件是否长时间没有被触发执行。

比如用户长时间不操作,就没有鼠标点击(click)事件、鼠标滚轮(mousewheel)事件、鼠标移动(mousemove)事件之类的,我们只需要监听这些事件,如果这些事件长时间没有触发,就说明用户长时间未操作,然后路由跳转到登录页面即可。

这三个事件我选择的是比较实用的鼠标点击事件,我们知道,一般来说项目的第一个页面是登录页面,所以在登录页面用户点击登录按钮的时候,就记录一下点击登录按钮的时间,存储到sessionstorage中去,当跳转到主页面的时候,当用户每点击一次页面,就更新一下sessionstorage中的存储的时间,同时也给页面绑定一个循环定时器,间隔一段时间就把当前时间和sessionstorage储存的上一次点击事件的时间做一个差值对比,当差值超过一定时间,就强制用户退出到登录页面即可。

代码

login.vue页面

// html
<el-button type="primary" @click="loginIn">点击登录</el-button>

// js
methods: {
    loginIn() {
      // 存第一份点击的时间
      sessionStorage.setItem("lastClickTime", new Date().getTime());
      // 模拟后端返回存一个token
      sessionStorage.setItem('token',"token")
      this.$router.push({
        path: "/",
      });
    },
}

Home.vue页面

<template>
  <div class="homeBox">
    <!-- 左边是菜单层级 -->
    <div class="left">
      <div class="leftNav">
        <el-menu
          :default-active="activeIndex"
          class="elMenu"
          background-color="#333"
          text-color="#B0B0B2"
          active-text-color="#fff"
          :unique-opened="true"
          router
          ref="elMenu"
        >
          <el-menu-item index="/vue">
            <i class="el-icon-location-outline"></i>
            <span slot="title">vue页面</span>
          </el-menu-item>
          <el-menu-item index="/react">
            <i class="el-icon-star-off"></i>
            <span slot="title">react页面</span>
          </el-menu-item>
          <el-menu-item index="/angular">
            <i class="el-icon-pear"></i>
            <span slot="title">angular页面</span>
          </el-menu-item>
        </el-menu>
      </div>
    </div>
    <!-- 右边是视图层级 -->
    <div class="right">
      <div class="rightTop">
        <el-button type="primary" plain @click="loginOut">登出</el-button>
      </div>
      <div class="rightBottom">
        <router-view></router-view>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: "Home",
  data() {
    return {
      activeIndex: this.$route.path,
      timer: null,
    };
  },
  created() {
    /*
      第一步:
        组件初始化加载就绑定监听点击事件,注意:addEventListener的第三个参数,这里要加上。
        因为第三个参数决定了是冒泡还是捕获(false冒泡默认,true捕获),因为绑定监听点击事件,我们是在最
        顶层的DOM位置进行捕获点击事件,所以第三个参数true,要加上的,这样的话,内层的任意地方的点击事件
        我们就都能监听到了,然后存储一下点击的时间
    */
    window.addEventListener(
      "click",
      () => {
        // 为了方便,我们把点击事件的时间直接存到sessionStorage中去,这样方便获取比较
        sessionStorage.setItem("lastClickTime", new Date().getTime());
      },
      true
    );
  },
  mounted() {
    /*
      第二步:
        组件初始化加载时也要绑定一个定时器,通过定时器定时轮询,去对比当前时间和上次点击的时间的差值
    */
    this.isTimeOut();
  },
  methods: {
    isTimeOut() {
      // 使用定时器之前,要清除一下定时器
      clearInterval(this.timer);
      this.timer = setInterval(() => {
        let lastClickTime = sessionStorage.getItem("lastClickTime") * 1; // 把上次点击时候的字符串时间转换成数字时间
        let nowTime = new Date().getTime(); // 获取当前时间
        console.log("当前时间和之前点击时间", nowTime, lastClickTime);
        // 假设我们需求是:5秒钟不进行点击操作,就提示登录退出
        if (nowTime - lastClickTime > 1000 * 5) {
          // 提示一下用户
          this.$message({ type: "warning", message: "超时了,已退出登录" });
          // 这里要清除定时器,结束任务
          clearInterval(this.timer);
          // 最后返回到登录页
          this.$router.push({ path: "/login" });
        }
      }, 1000);
    },
  },
  beforeDestroy() {
    // 最后一步,离开页面的时候,清除一下定时器,也解绑点击事件
    clearInterval(this.timer);
    window.removeEventListener("click", () => {}, true);
  },
};
</script>

这里注意一下,层级对应关系,我项目搭建的层级关系是Home.vue页面是App.vue页面的里面一层,也有对应的视图,视图对应的也是整个页面的关系。根据层级和路由表路由视图router-view关系,选择合适的层级去绑定对应的点击事件和定时器即可。

即层级关系是要选择和login.vue层级平行的下一级才行,否则就会在login.vue页面也会执行定时器和点击绑定事件了

效果图

后端控制(方式二)

思路

这种后端控制方式限制性没有前端控制强,但是也是可以用的。
我们知道用户长时间不操作就不会有发请求,这种方式我们和后端商定如下:
当用户这一次的请求和上一次请求的间隔时间超过一定时间,比如超过半小时。那么后端返回的状态码就不是200了,就是一个特殊的状态码,比如是4567这个状态码,那么我们在前端的响应拦截器中就可以加一个判断,如果状态码是4567就说明请求超时了,说明用户长时间未操作,这个时候直接路由跳转到登录页面即可

后端通过JWT机制去控制返回的状态码

代码

这里main.js中的Vue的实例对象我们将其挂载到全局对象window上,方便我们在响应拦截器中使用vm对象上的路由跳转方法

main.js文件

// 挂载到window对象上
window.vm = new Vue({
    store,
    router,
    render: h => h(App),
}).$mount('#app')

响应拦截器文件

http.interceptors.response.use((res) => {
    console.log('注册到全局上',vm);
    var code = res.data.code;
    if(code == 4567){ // 4567是超时状态码,看到这个标识我们就让用户退出登录
        // 注意,这个时候路由跳转就不是this.$router.push()了
        vm._router.push({ path: "/login" });
    }
    return res.data
}, (error) => {
    // console.log(error)
    return Promise.reject(error);
})

打印vm实例对象

所以在响应拦截器中路由跳转变成了vm._router.push({ path: "/login" })了

总结

上述两种方式的思路都可以使用,具体使用哪种方式,视情况而定

到此这篇关于vue用户长时间不操作退出到登录页的两种实现方式的文章就介绍到这了,更多相关vue用户长时间不操作退出内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • vue中js判断长时间不操作界面自动退出登录(推荐)

    需求说明,后台有做半个小时不请求接口的话返回标识退出登录,但是要请求接口才行,现在要实现前端用js判断半个小时不操作界面的话自动跳转到登录页面. 创建一个.js文件,在main.js引入此js(vue框架) 在登录成功的时候保存当前时间localStorage.setItem("lastTime",new Date().getTime()); 然后在点击的时候更新这个时间 var lastTime = new Date().getTime(); var currentTime = ne

  • vue实现用户长时间不操作自动退出登录功能的实现代码

    一.需求说明 昨天后端开发人员让我实现一个网页锁屏,当时我一头雾水,问他为啥搞的跟安卓系统一样.他的回复是"看起来帅点". 首先我们梳理下逻辑,先来个简化版的,用户长时间未操作时,返回登录页 二.思路 使用 mouseover 事件来监测是否有用户操作页面,写一个定时器间隔特定时间检测是否长时间未操作页面,如果是,退出登陆,清除token,返回登录页 三.实现 [1]在util文件夹下创建一个storage.js封装localStorage方法 export default { set

  • vue用户长时间不操作退出到登录页的两种实现方式

    目录 问题描述 前端控制(方式一) 思路 代码 后端控制(方式二) 思路 代码 总结 问题描述 产品说,出于安全考虑,用户长时间不操作,就回到登录页面,让用户重新登录,就像银行的app一样.本文就记录一下实现这种效果的两种方式,分别是前端控制和后端控制,各有细节及适用使用场景 前端控制(方式一) 思路 首先,用户长时间不操作具体表现形式是啥?其实就是事件是否长时间没有被触发执行. 比如用户长时间不操作,就没有鼠标点击(click)事件.鼠标滚轮(mousewheel)事件.鼠标移动(mousem

  • Vue设置长时间未操作登录自动到期返回登录页

    Vue设置长时间未操作登录以后自动到期返回登录页 首先我们写在main.js文件中 import routerUtil from "@/utils/routerutil";//先将js文件在main.js中引入 routerUtil(router); 我们会在登陆成功后调用sessionUtil文件中的setSession,sessionUtil下面写的有 import sessionUtil from '@/utils/sessionutil' sessionUtil.setSess

  • vue实现Excel文件的上传与下载功能的两种方式

    一.前言项目中使用到比较多的关于Excel的前端上传与下载,整理出来,以便后续使用或分析他人. 1.前端vue:模板下载与导入Excel 导入Excel封装了子组件,点击导入按钮可调用子组件,打开文件上传的对话框,上传成功后返回结果 <el-col style="padding: 10px 0 20px;"> <el-button class="pull-right" icon="el-icon-upload" type=&qu

  • vue+axios 前端实现登录拦截的两种方式(路由拦截、http拦截)

    一.路由拦截 登录拦截逻辑 第一步:路由拦截 首先在定义路由的时候就需要多添加一个自定义字段requireAuth,用于判断该路由的访问是否需要登录.如果用户已经登录,则顺利进入路由, 否则就进入登录页面. const routes = [ { path: '/', name: '/', component: Index }, { path: '/repository', name: 'repository', meta: { requireAuth: true, // 添加该字段,表示进入这个

  • 国产化中的 .NET Core 操作达梦数据库DM8的两种方式(操作详解)

    目录 背景 环境 SDK 操作数据库 DbHelperSQL方式 Dapper方式 背景 某个项目需要实现基础软件全部国产化,其中操作系统指定银河麒麟,数据库使用达梦V8,CPU平台的范围包括x64.龙芯.飞腾.鲲鹏等.考虑到这些基础产品对.NET的支持,最终选择了.NET Core 3.1. 环境 CPU平台:x86-64 / Arm64 操作系统:银河麒麟 v4 数据库:DM8 .NET:.NET Core 3.1 SDK 达梦自己提供了.NET操作其数据库的SDK,可以通过NuGet安装,

  • vue动态子组件的两种实现方式

    文章目录 方式一:局部注册所需组件 使用缓存 方式二:动态注册组件实现 让多个组件使用同一个挂载点,并动态切换,这就是动态组件. 通过使用保留的 <component>元素,动态地绑定到它的 is 特性,可以实现动态组件. 方式一:局部注册所需组件 <div id="example"> <button @click="change">切换页面</button> <component :is="curre

  • Vue.js项目中管理每个页面的头部标签的两种方法

    在 Vue SPA 应用中,如果想要修改 HTML 的头部标签,如页面的 title ,我们只能去修改 index.html 模板文件,但是这个是全局的修改,如何为每个页面都设置不一样的 title 呢?下面介绍两种方法. 使用router.meta 在路由里面配置每个路由的地址: routes: [ { /* (首页)默认路由地址 */ path: '/', name: 'Entrance', component: Entrance, meta: { title: '首页入口' } }, {

  • Vue中keep-alive的两种应用方式

    Vue中keep-alive的使用我总结的有两种方式应用: 首先简述一下keep-alive的作用,kee-alive可以缓存不活动的的组件.当组件之间进行相互切换的时候,默认会销毁,当重新切换回来时又重新初始化.现在有需求切换回来不销毁组件,保持原来的状态,此时用keep-alive就可以实现了 我创建了两个组件,可以相互切换 组件1: 组件2: 第一种方式 在组件1的路由中添加 meta: { keepAlive: true }, 也就是当前路由需要缓存 此时路由设置完毕,keep-aliv

  • Vue弹窗的两种实现方式实例详解

    目录 方法一 使用.sync修饰符 方法二 使用v-model 方法一 使用.sync修饰符 element就是使用的这种方式,实现方式如下: 父组件: <template> <div id="demo"> <test-model :show.sync="showFlag"></test-model> </div> </template> <script> import testMo

随机推荐