基于Vue.js實現(xiàn)一個完整的登錄功能
1. 引言
用戶登錄功能是Web應(yīng)用中最常見的功能之一。它通常包括表單輸入、數(shù)據(jù)驗證、接口調(diào)用、狀態(tài)管理等多個步驟。在Vue.js中,我們可以通過組合使用Vue組件、Vuex狀態(tài)管理、Axios網(wǎng)絡(luò)請求等技術(shù)來實現(xiàn)一個完整的登錄功能。
本文將基于一個實際的Vue.js項目代碼,詳細(xì)解析登錄功能的實現(xiàn)過程。我們將從表單的實現(xiàn)開始,逐步深入到表單驗證、接口調(diào)用、狀態(tài)管理以及登錄成功與失敗的處理。
2. 項目結(jié)構(gòu)概述
在開始之前,我們先簡單了解一下項目的結(jié)構(gòu)。項目的登錄功能主要由以下幾個部分組成:
- 登錄組件:負(fù)責(zé)渲染登錄表單,并處理用戶的輸入。
- Vuex Store:負(fù)責(zé)管理用戶登錄狀態(tài),包括登錄請求的發(fā)起和響應(yīng)處理。
- API模塊:負(fù)責(zé)與后端接口進(jìn)行通信,發(fā)送登錄請求并接收響應(yīng)。
3. 登錄表單的實現(xiàn)
登錄表單是用戶與系統(tǒng)交互的入口。在我們的項目中,登錄表單使用了Ant Design Vue組件庫來實現(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="賬戶或密碼錯誤" />
<!-- 登錄方式選擇 -->
<a-radio-group v-model="loginType" style="margin-bottom: 24px;">
<a-radio-button value="account">賬號密碼登錄</a-radio-button>
<a-radio-button value="phone">手機號登錄</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>
<!-- 手機號登錄 -->
<div v-if="loginType === 'phone'">
<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="phoneDom"
v-decorator="[
'phone',
{rules: [{ required: true, message: '請輸入手機號' }], 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="200px">
<a-form-item>
<a-input
size="small"
type="text"
placeholder=""
ref="captchaDom"
v-decorator="[
'captcha',
{rules: [{ required: true, message: '請輸入驗證碼' }], 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}秒后重新獲取` : '獲取驗證碼' }}
</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>
在這個表單中,我們使用了a-form組件來包裹整個表單,并通過v-decorator指令來實現(xiàn)表單驗證。用戶可以選擇通過賬號密碼或手機號登錄,表單會根據(jù)用戶的選擇動態(tài)渲染不同的輸入項。
4. 表單驗證
表單驗證是確保用戶輸入數(shù)據(jù)合法性的重要步驟。在我們的項目中,表單驗證通過Ant Design Vue的v-decorator指令來實現(xià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)行驗證。如果驗證通過,則構(gòu)造登錄參數(shù)并調(diào)用Login方法進(jìn)行登錄。
5. 登錄接口的調(diào)用
登錄接口的調(diào)用是通過Vuex的action來實現(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會在Vuex store中定義,通常使用Axios來發(fā)送HTTP請求。
6. Vuex狀態(tài)管理
Vuex是Vue.js的官方狀態(tài)管理庫,用于管理應(yīng)用中的共享狀態(tài)。在我們的項目中,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兩個action,分別用于處理登錄和注銷操作。登錄成功后,我們會將用戶信息和token存儲到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: '錯誤',
description: ((err.response || {}).data || {}).message || '請求出現(xiàn)錯誤,請稍后再試',
duration: 4
})
}
}
在loginSuccess方法中,我們將用戶信息存儲到Vuex state中,并跳轉(zhuǎn)到首頁。在requestFailed方法中,我們顯示錯誤信息,提示用戶登錄失敗。
8. 總結(jié)
通過本文的詳細(xì)解析,我們了解了如何在Vue.js項目中實現(xiàn)一個完整的登錄功能。我們從表單的實現(xiàn)開始,逐步深入到表單驗證、接口調(diào)用、狀態(tài)管理以及登錄成功與失敗的處理。希望本文能幫助開發(fā)者更好地理解和實現(xiàn)類似功能。
在實際開發(fā)中,登錄功能可能會更加復(fù)雜,涉及到更多的安全性和用戶體驗優(yōu)化。但無論如何,掌握這些基礎(chǔ)知識是構(gòu)建一個健壯的登錄功能的前提。
以上就是基于Vue.js實現(xiàn)一個完整的登錄功能的詳細(xì)內(nèi)容,更多關(guān)于Vue.js登錄功能的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
vue3?setup中父組件通過Ref調(diào)用子組件的方法(實例代碼)
這篇文章主要介紹了vue3?setup中父組件通過Ref調(diào)用子組件的方法,本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-08-08

