基于Vue.js實(shí)現(xiàn)一個(gè)完整的登錄功能
1. 引言
用戶登錄功能是Web應(yīng)用中最常見的功能之一。它通常包括表單輸入、數(shù)據(jù)驗(yàn)證、接口調(diào)用、狀態(tài)管理等多個(gè)步驟。在Vue.js中,我們可以通過組合使用Vue組件、Vuex狀態(tài)管理、Axios網(wǎng)絡(luò)請求等技術(shù)來實(shí)現(xiàn)一個(gè)完整的登錄功能。
本文將基于一個(gè)實(shí)際的Vue.js項(xiàng)目代碼,詳細(xì)解析登錄功能的實(shí)現(xiàn)過程。我們將從表單的實(shí)現(xiàn)開始,逐步深入到表單驗(yàn)證、接口調(diào)用、狀態(tài)管理以及登錄成功與失敗的處理。
2. 項(xiàng)目結(jié)構(gòu)概述
在開始之前,我們先簡單了解一下項(xiàng)目的結(jié)構(gòu)。項(xiàng)目的登錄功能主要由以下幾個(gè)部分組成:
- 登錄組件:負(fù)責(zé)渲染登錄表單,并處理用戶的輸入。
- Vuex Store:負(fù)責(zé)管理用戶登錄狀態(tài),包括登錄請求的發(fā)起和響應(yīng)處理。
- API模塊:負(fù)責(zé)與后端接口進(jìn)行通信,發(fā)送登錄請求并接收響應(yīng)。
3. 登錄表單的實(shí)現(xiàn)
登錄表單是用戶與系統(tǒng)交互的入口。在我們的項(xiàng)目中,登錄表單使用了Ant Design Vue
組件庫來實(shí)現(xiàn)。以下是登錄表單的核心代碼:
<template> <a-col class="main line_input"> <a-form id="formLogin" class="user-layout-login" ref="formLogin" :form="form" hideRequiredMark @submit="handleSubmit" > <div class="title"><span>1nmob</span></div> <a-alert v-if="isLoginError" type="error" showIcon style="margin-bottom: 24px;" message="賬戶或密碼錯(cuò)誤" /> <!-- 登錄方式選擇 --> <a-radio-group v-model="loginType" style="margin-bottom: 24px;"> <a-radio-button value="account">賬號密碼登錄</a-radio-button> <a-radio-button value="phone">手機(jī)號登錄</a-radio-button> </a-radio-group> <!-- 賬號密碼登錄 --> <div v-if="loginType === 'account'"> <a-row type="flex" class="padding_bottom"> <a-col flex="58px"> <span class="labels">賬號:</span> </a-col> <a-col flex="310px"> <a-form-item> <a-input size="small" type="text" placeholder="" ref="userCodeDom" v-decorator="[ 'userCode', {rules: [{ required: true, message: '請輸入帳戶名或郵箱地址' }, { validator: handleuserCodeOrEmail }], validateTrigger: 'change'} ]" > </a-input> </a-form-item> </a-col> </a-row> <a-row type="flex"> <a-col flex="58px"> <span class="labels">密碼:</span> </a-col> <a-col flex="310px"> <a-form-item> <a-input-password size="small" class="my_password" placeholder="" ref="pwdDom" v-decorator="[ 'pwd', {rules: [{ required: true, message: '請輸入密碼' }], validateTrigger: 'blur'} ]" > </a-input-password> </a-form-item> </a-col> </a-row> </div> <!-- 手機(jī)號登錄 --> <div v-if="loginType === 'phone'"> <a-row type="flex" class="padding_bottom"> <a-col flex="58px"> <span class="labels">手機(jī)號:</span> </a-col> <a-col flex="310px"> <a-form-item> <a-input size="small" type="text" placeholder="" ref="phoneDom" v-decorator="[ 'phone', {rules: [{ required: true, message: '請輸入手機(jī)號' }], validateTrigger: 'change'} ]" > </a-input> </a-form-item> </a-col> </a-row> <a-row type="flex"> <a-col flex="58px"> <span class="labels">驗(yàn)證碼:</span> </a-col> <a-col flex="200px"> <a-form-item> <a-input size="small" type="text" placeholder="" ref="captchaDom" v-decorator="[ 'captcha', {rules: [{ required: true, message: '請輸入驗(yàn)證碼' }], validateTrigger: 'blur'} ]" > </a-input> </a-form-item> </a-col> <a-col flex="110px"> <a-button size="small" :disabled="state.smsSendBtn" @click="getCaptcha" > {{ state.smsSendBtn ? `${state.time}秒后重新獲取` : '獲取驗(yàn)證碼' }} </a-button> </a-col> </a-row> </div> <a-form-item> <router-link :to="{ name: 'recover', params: { user: 'aaa'} }" class="forge-password" style="float: right;" >忘記密碼?</router-link> </a-form-item> <div style="textAlign:center"> <a-form-item style="margin-bottom:0px"> <a-button size="large" type="primary" htmlType="submit" class="login-button" :loading="state.loginBtn" :disabled="state.loginBtn" >確定</a-button> </a-form-item> </div> </a-form> </a-col> </template>
在這個(gè)表單中,我們使用了a-form組件來包裹整個(gè)表單,并通過v-decorator指令來實(shí)現(xiàn)表單驗(yàn)證。用戶可以選擇通過賬號密碼或手機(jī)號登錄,表單會(huì)根據(jù)用戶的選擇動(dòng)態(tài)渲染不同的輸入項(xiàng)。
4. 表單驗(yàn)證
表單驗(yàn)證是確保用戶輸入數(shù)據(jù)合法性的重要步驟。在我們的項(xiàng)目中,表單驗(yàn)證通過Ant Design Vue的v-decorator指令來實(shí)現(xiàn)。以下是表單驗(yàn)證的核心代碼:
methods: { handleuserCodeOrEmail (rule, value, callback) { const { state } = this const regex = /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+((\.[a-zA-Z0-9_-]{2,3}){1,2})$/ if (regex.test(value)) { state.loginType = 0 } else { state.loginType = 1 } callback() }, handleSubmit (e) { e.preventDefault() const { form: { validateFields }, state, loginType, Login } = this state.loginBtn = true const validateFieldsKey = loginType === 'account' ? ['userCode', 'pwd'] : ['phone', 'captcha'] validateFields(validateFieldsKey, { force: true }, (err, values) => { if (!err) { const loginParams = { ...values } if (loginType === 'account') { delete loginParams.userCode loginParams[!state.loginType ? 'email' : 'userCode'] = values.userCode loginParams.pwd = md5(values.pwd) } else { loginParams.phone = values.phone loginParams.captcha = values.captcha } Login(loginParams) .then((res) => { if (res.code === this.CONSTVAL.SUCCESSCODE) { this.loginSuccess(res) } else { this.requestFailed(res) } }) .catch(err => this.requestFailed(err)) .finally(() => { state.loginBtn = false }) } else { setTimeout(() => { state.loginBtn = false }, 600) } }) } }
在handleSubmit
方法中,我們首先調(diào)用validateFields
方法對表單進(jìn)行驗(yàn)證。如果驗(yàn)證通過,則構(gòu)造登錄參數(shù)并調(diào)用Login
方法進(jìn)行登錄。
5. 登錄接口的調(diào)用
登錄接口的調(diào)用是通過Vuex的action
來實(shí)現(xiàn)的。以下是登錄接口調(diào)用的核心代碼:
methods: { ...mapActions(['Login', 'Logout']), handleSubmit (e) { e.preventDefault() const { form: { validateFields }, state, loginType, Login } = this state.loginBtn = true const validateFieldsKey = loginType === 'account' ? ['userCode', 'pwd'] : ['phone', 'captcha'] validateFields(validateFieldsKey, { force: true }, (err, values) => { if (!err) { const loginParams = { ...values } if (loginType === 'account') { delete loginParams.userCode loginParams[!state.loginType ? 'email' : 'userCode'] = values.userCode loginParams.pwd = md5(values.pwd) } else { loginParams.phone = values.phone loginParams.captcha = values.captcha } Login(loginParams) .then((res) => { if (res.code === this.CONSTVAL.SUCCESSCODE) { this.loginSuccess(res) } else { this.requestFailed(res) } }) .catch(err => this.requestFailed(err)) .finally(() => { state.loginBtn = false }) } else { setTimeout(() => { state.loginBtn = false }, 600) } }) } }
在handleSubmit
方法中,我們通過Login
action來調(diào)用登錄接口。Login
action會(huì)在Vuex store中定義,通常使用Axios來發(fā)送HTTP請求。
6. Vuex狀態(tài)管理
Vuex是Vue.js的官方狀態(tài)管理庫,用于管理應(yīng)用中的共享狀態(tài)。在我們的項(xiàng)目中,Vuex負(fù)責(zé)管理用戶登錄狀態(tài)。以下是Vuex store的核心代碼:
import Vue from 'vue' import Vuex from 'vuex' import axios from 'axios' Vue.use(Vuex) export default new Vuex.Store({ state: { user: null, token: null }, mutations: { setUser (state, user) { state.user = user }, setToken (state, token) { state.token = token } }, actions: { Login ({ commit }, loginParams) { return axios.post('/api/login', loginParams) .then(response => { commit('setUser', response.data.user) commit('setToken', response.data.token) return response }) }, Logout ({ commit }) { commit('setUser', null) commit('setToken', null) } } })
在Vuex store中,我們定義了Login
和Logout
兩個(gè)action,分別用于處理登錄和注銷操作。登錄成功后,我們會(huì)將用戶信息和token存儲(chǔ)到state中。
7. 登錄成功與失敗的處理
登錄成功或失敗后,我們需要根據(jù)接口返回的結(jié)果進(jìn)行相應(yīng)的處理。以下是登錄成功與失敗處理的代碼:
methods: { loginSuccess (res) { this.setUserCode(res.data.userCode) this.setAccessWay(res.data.accessWay) this.setUserPic(res.data.userPic) this.setCompanyId(res.data.companyId) this.setAccountType(res.data.accessWay) this.setTokenTime(res.data.tokenTime) this.$router.push({ path: '/' }) setTimeout(() => { this.$notification.success({ message: '歡迎', description: `${timeFix()},歡迎回來` }) }, 1000) this.isLoginError = false }, requestFailed (err) { this.isLoginError = true this.$notification['error']({ message: '錯(cuò)誤', description: ((err.response || {}).data || {}).message || '請求出現(xiàn)錯(cuò)誤,請稍后再試', duration: 4 }) } }
在loginSuccess
方法中,我們將用戶信息存儲(chǔ)到Vuex state中,并跳轉(zhuǎn)到首頁。在requestFailed
方法中,我們顯示錯(cuò)誤信息,提示用戶登錄失敗。
8. 總結(jié)
通過本文的詳細(xì)解析,我們了解了如何在Vue.js項(xiàng)目中實(shí)現(xiàn)一個(gè)完整的登錄功能。我們從表單的實(shí)現(xiàn)開始,逐步深入到表單驗(yàn)證、接口調(diào)用、狀態(tài)管理以及登錄成功與失敗的處理。希望本文能幫助開發(fā)者更好地理解和實(shí)現(xiàn)類似功能。
在實(shí)際開發(fā)中,登錄功能可能會(huì)更加復(fù)雜,涉及到更多的安全性和用戶體驗(yàn)優(yōu)化。但無論如何,掌握這些基礎(chǔ)知識是構(gòu)建一個(gè)健壯的登錄功能的前提。
以上就是基于Vue.js實(shí)現(xiàn)一個(gè)完整的登錄功能的詳細(xì)內(nèi)容,更多關(guān)于Vue.js登錄功能的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Vue Render函數(shù)原理及代碼實(shí)例解析
這篇文章主要介紹了Vue Render函數(shù)原理及代碼實(shí)例解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-07-07vue3?setup中父組件通過Ref調(diào)用子組件的方法(實(shí)例代碼)
這篇文章主要介紹了vue3?setup中父組件通過Ref調(diào)用子組件的方法,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-08-08