Vue.js寫一個SPA登錄頁面的過程

来源:http://www.cnblogs.com/jiaoyu121/archive/2017/06/22/7067715.html
-Advertisement-
Play Games

技術棧 vue.js 主框架 vuex 狀態管理 vue-router 路由管理 一般過程 在一般的登錄過程中,一種前端方案是: 下麵我根據列出的步驟一一分析如何做代碼實現,所有在代碼在https://github.com/doterlin/vue-example-login中,並帶有較詳細註釋幫助 ...


技術棧

一般過程

在一般的登錄過程中,一種前端方案是:

  1. 檢查狀態:進入頁面時或者路由變化時檢查是否有登錄狀態(保存在cookie或者本地存儲的值);
  2. 如果有登錄態則查詢登錄信息(uid,頭像等...)並保存起來;如果沒有則跳轉到登錄頁;
  3. 在登錄頁面(或者登錄框),校檢用戶輸入信息是否合法;
  4. 校檢通過後發送登錄請求;校檢不成功則反饋給用戶;
  5. 登錄成功則從後端數據中取出session信息保存登錄狀態(可能需要跳轉);登錄不成功則提示用戶不成功;
  6. 用戶做出註銷操作時刪除登錄狀態。

下麵我根據列出的步驟一一分析如何做代碼實現,所有在代碼在https://github.com/doterlin/vue-example-login中,並帶有較詳細註釋幫助理解代碼。

在此之前假設登錄頁面路由為/login,登錄後的路由為/user_info。這樣只需要在App.vue放好router-view用於存放和渲染這兩個路由。

// component/App.vue
<template>
<div class="container" id="app">
  <transition name="fade">
    <keep-alive>
      <router-view></router-view>
    </keep-alive>
  </transition>
</div>
</template>
...

並做好vue-router配置:

// js/app.js
import Vue from 'vue'
import VueRouter from 'vue-router'
import Login from '../component/Login.vue'
import UserInfo from '../component/UserInfo.vue'

Vue.use(VueRouter);
const router = new VueRouter({
  routes: [{
    path: '/login',
    component: Login
  }, {
    path: '/user_info',
    component: UserInfo
  }]
})
...

檢查狀態與跳轉

在兩個時候我們需要檢查狀態:1.用戶打開頁面時; 2.路由發生變化時;

首先需要寫好一個檢查登錄態的方法checkLogin

// js/app.js
...
var app = new Vue({
  data: {},
  el: '#app',
  render: h => h(App),
  router,
  store,
  methods:{
    checkLogin(){
      //檢查是否存在session
      //cookie操作方法在源碼里有或者參考網上的即可
      if(!this.getCookie('session')){
        //如果沒有登錄狀態則跳轉到登錄頁
        this.$router.push('/login');
      }else{
        //否則跳轉到登錄後的頁面
        this.$router.push('/user_info');
      }
    }
  }
})

為了提升用戶體驗,當用戶打開頁面時前端需要檢查他是否已經登錄,不需要用戶再次登錄。這個實現很簡單,我們在vue實例created鉤子里寫好:

// js/app.js
...
var app = new Vue({
  ...
  created() {
    this.checkLogin();
  },
  methods:{
    checkLogin(){
     ...
    }
  }
})

另外,路由發生變化時也需要檢查登錄,以下情景(路由變化)如果我們不檢查登錄態可能會發生錯誤:

  • 用戶在進入頁面時存在登錄狀態,但在做操作時正好登錄過期了;
  • 用戶手動刪除了cookie/本地storage並做操作;
  • 用戶在未登錄的情況下手動輸入(或者從收藏夾進入)某個需要登錄的路由
  • 用戶在已登錄的情況下進入登錄頁路由

這些足夠成為我們監聽路由的理由,實現的話可以利用vuewatch功能:

// js/app.js
...
var app = new Vue({
  ...
  //監聽路由檢查登錄
  watch:{
    "$route" : 'checkLogin'
  },

  //進入頁面時
  created() {
    this.checkLogin();
  },

  methods:{
    checkLogin(){
     ...
    }
  }
})

至此,我們就完成了一般過程中的第1步。接下來實現如何獲取用戶個人信息。

獲取用戶信息

在成功登錄後,我們一般需要從後端顯示用戶的一些信息,比如昵稱,頭像,等級等等...獲取的話很簡單,發一個http請求從後端拉取;但是一般這些信息會在多的路由用到(比如uid一般都需要在各個後端介面中作為參數帶上),所以需要保存到全局狀態中(vuex):

// component/App.vue
...
<script>
export default {
  ...
  mounted(){
    //組件開始掛載時獲取用戶信息
    this.getUserInfo();
  },
  methods: {
    //請求用戶的一些信息
    getUserInfo(){
      this.userInfo = {
        nick: 'Doterlin',
        ulevel: 20,
        uid: '10000',
        portrait: 'images/profile.png'
      }

      //獲取信息請求
      ts.$http.get(url, {
        //參數
        "params": this.userInfo
      }).then((response) => {
        //Success
        if(response.data.code == 0){
          this.$store.commit('updateUserInfo', this.userInfo); 
        }
      }, (response) => {
        //Error
      });

    }
  }
}
</script>
...

當然我們需要在之前配置好,比如在寫在app.js或者單獨寫成store.js併在app.js引入(推薦):

// js/app.js
// Vuex配置
...
const store = new Vuex.Store({
  state: {
    domain:'http://test.example.com', //保存後臺請求的地址,修改時方便(比方說從測試服改成正式服功能變數名稱)
    userInfo: { //保存用戶信息
      nick: null,
      ulevel: null,
      uid: null,
      portrait: null
    }
  },
  mutations: {
    //更新用戶信息
    updateUserInfo(state, newUserInfo) {
      state.userInfo = newUserInfo;
    }
  }
})
...

輸入校驗和發送登錄請求

為了防止一些不符合預期的字元和過於頻繁的請求傳到後臺,前端要對用戶的輸入進行校驗和防止重覆請求。當然不同網站的合法字元不一樣,這裡只做為空時不合法的校驗:

//component/Login.vue
<template>
<div class="login" id="login">
   ...
    <div class="log-email">
        <input type="text" placeholder="Email" :class="'log-input' + (account==''?' log-input-empty':'')" v-model="account"><input type="password" placeholder="Password" :class="'log-input' + (password==''?' log-input-empty':'')"  v-model="password">
        <a href="javascript:;" class="log-btn" @click="login">Login</a>
    </div>
    ...
</div>
</template>
<script>
import Loading from './Loading.vue'
export default {
  name: 'Login',
  data(){
      return {
          isLoging: false,
          account: '',
          password: ''
      }
  },
  components:{
    Loading
  },
  methods:{

      //登錄邏輯
      login(){
          if(this.account!='' && this.password!=''){
              this.toLogin();
          }
      }

}
</script>
...

這裡的this.toLogin就是登錄請求的方法,在post密碼到後端時不是直接發送,一般會按照後端定的規則加密後在發送,比如哈希演算法,例子進行了的雙重哈希加密,引用了js/sha1.min.js,大致實現如下:

...
      //登錄請求
      toLogin(){

          //一般要跟後端瞭解密碼的加密規則
          //這裡例子用的哈希演算法來自./js/sha1.min.js
          let password_sha = hex_sha1(hex_sha1( this.password ));

          //需要想後端發送的登錄參數
          let loginParam = {
              account: this.account,
              password_sha
          }

          //設置在登錄狀態
          this.isLoging = true;

          //請求後端
          this.$http.post( 'example.com/login.php', {
          param: loginParam).then((response) => {
            if(response.data.code == 1){
              //如果登錄成功則保存登錄狀態並設置有效期
              let expireDays = 1000 * 60 * 60 * 24 * 15;
              this.setCookie('session', response.data.session, expireDays);
              //跳轉
              this.$router.push('/user_info'); 
            }
          }, (response) => {
            //Error
          });

...

這樣就完成了第3,4,5個步驟了。最後一步就是註銷。

註銷

註銷時有的需要請求後端有的不需要,關鍵的事要刪除保存的登錄狀態:

// component/UserInfo.vue
...
   logout(){
      //刪除cookie並跳到登錄頁
      this.isLogouting = true;
      //請求後端,比如logout.php
      // this.$http.post('eaxmple.com/logout.php')...
      //成功後刪除cookie
      this.delCookie('session');

      //重置loding狀態
      this.isLogouting = false;

      //跳轉到登錄頁
      this.$router.push('/login/');
    }
...


學習過程中遇到什麼問題或者想獲取學習資源的話,歡迎加入學習交流群
343599877,我們一起學前端!


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 反射機制的定義: 在運行狀態時(動態的),對於任意一個類,都能夠得到這個類的所有屬性和方法。 對於任意一個對象,都能夠調用它的任意屬性和方法。 Class類是反射機制的起源,我們得到Class類對象有3種方法: 第一種:通過類名獲得 Class<?> class = ClassName.class; ...
  • #-*- coding:utf-8 -*- ...
  • 題目描述 Bessie像她的諸多姊妹一樣,因為從Farmer John的草地吃了太多美味的草而長出了太多的贅肉。所以FJ將她置於一個及其嚴格的節食計劃之中。她每天不能吃多過H (5 <= H <= 45,000)公斤的乾草。 Bessie只能吃一整捆乾草;當她開始吃一捆乾草的之後就再也停不下來了。她 ...
  • 本文主要講述分散式系統開發的一些相關理論基礎。 一、ACID ACID是一系列對系統中數據進行訪問與更新的操作所組成的一個程式執行的邏輯單元,狹義上的事務特指資料庫事務。 1、Atomic原子性 事務必須是一個原子的操作序列單元,事務中包含的各項操作在一次執行過程中,要麼全部執行成功,要麼全部不執行 ...
  • 【原創出品§轉載請註明出處】 出處:http://www.cnblogs.com/libra13179/p/7064321.html 什麼東西?? 我們先來看我們平常看到SPI的時序圖(呵呵,要是忘記了可以去我之前寫 SPI線協議詳解) 現在我們來看看USART的同步模式Synchronous 是不 ...
  • [1]基本實例 [2]條紋狀表格 [3]帶邊框的表格 [4]滑鼠懸停 [5]緊縮表格 [6]狀態類 [7]響應式表格 ...
  • npm作為國外的node倉庫安裝工具,自然會受到我大長城防火牆的干擾,國內用戶在安裝相關的資源的時候,會出現安裝失敗,以及速度很慢的情況。為瞭解決npm安裝的問題,國內出現了很多npm的鏡像網址,taobao的npm鏡像算是使用頻率比較高的了。 使用的方法我知道的有三種,首先是淘寶npm自己提供的兩 ...
  • 1. 嵌套操作 子操作: > div>ul>li <div> <ul> <li></li> </ul> </div> 併列:+ div+ul>li <div></div> <ul> <li></li> </ul> 上級:^ ul>li^div <ul> <li></li> </ul> <div></ ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...