1. 程式人生 > 程式設計 >vue使用者長時間不操作退出到登入頁的兩種實現方式

vue使用者長時間不操作退出到登入頁的兩種實現方式

目錄
  • 問題描述
  • 前端控制(方式一)
    • 思路
    • 程式碼
  • 後端控制(方式二)
    • 思路
    • 程式碼
  • 總結

    問題描述

    產品說,出於安全考慮,使用者長時間不操作,就回到登入頁面,讓使用者重新登入,就像銀行的app一樣。本文就記錄一下實現這種效果的兩種方式,分別是前端控制和後端控制,各有細節及適用使用場景

    前端控制(方式一)

    思路

    首先,使用者長時間不操作具體表現形式是啥?其實就是事件是否長時間沒有被觸發執行。

    比如使用者長時間不操作,就沒有滑鼠點選(click)事件、滑鼠滾輪(mousewheel)事件、滑鼠移動(mousemove)事件之類的,我們只需要監聽這些事件,如果這些事件長時間沒有觸發,就說明使用者長時間未操作,然後路由跳轉到登入頁面即可。

    這三個事件我選擇的是比較實用的滑鼠點選事件,我們知道,一般來說專案的第一個頁面是登入頁面,所以在登入頁面使用者點選登入按鈕的時候,就記錄一下點選登入按鈕的時間,儲存到sessionstorage中去,當跳轉到主頁面的時候,當用戶每點選一次頁面,就更新一下sessionstorage中的儲存的時間,同時也給頁面繫結一個迴圈定時器,間隔一段時間就把當前時間和sessionstorage儲存的上一次點選事件的時間做一個差值對比,當差值超過一定時間,就強制使用者退出到登入頁面即可。

    程式碼

    login.頁面

    // html
    <el-button type="primary" @click="loginIn">點選登入</el-button>
    
    // 
    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-iconhttp://www.cppcns.com
    -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() { /* 第二步: 元件初HgNFhCjx始化載入時也要繫結一個定時器,通過定時器定時輪詢,去對比當前時間和上次點選的時間的差值 */ 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頁面也會執行定時器和點選繫結事件了

    效果圖

    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()了
            vhttp://www.cppcns.comm._router.push({ path: "/login" });
        }
        return res.data
    },(error) => {
        // console.log(error)
        return Promise.reject(error);
    })
    

    列印vm例項物件

    vue使用者長時間不操作退出到登入頁的兩種實現方式

    所以在響應攔截器中路由跳轉變成了vm._router.push({ path: "/login" })了

    總結

    上述兩種方式的思路都可以使用,具體使用哪種方式,視情況而定

    到此這篇關於vue使用者長時間不操作退出到登入頁的兩種實現方式的文章就介紹到這了,更多相關vue使用者長時間不操作退出內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!