Vue.js實現(xiàn)可配置的登錄表單代碼詳解
表單是后臺項目業(yè)務(wù)中的常用組件,這次重構(gòu)了登錄功能以滿足登錄方式可配置的需求,在此記錄和分享一下。
業(yè)務(wù)場景
在之前,項目只支持手機(jī)號+密碼登錄,前端是直接把表單寫死的,后來有客戶希望能支持驗證碼登錄,有的客戶還希望能有手機(jī)號+驗證碼+密碼的登錄方式…所以登錄方式的靈活性需要可配置的表單支持,于是我把登錄組件做了拆分。
以表單元素為粒度,分離出了手機(jī)號、密碼、短信驗證碼這幾個組件,它們內(nèi)部都有自己的表單驗證方法,通過組合可以快速完成登錄、注冊、找回密碼等表單組件。高內(nèi)聚低耦合、高內(nèi)聚低耦合…跟著念十遍~
. ├ common ├ captcha.vue | ├ password.vue | └ phone.vue ├ login | └ index.vue ├ register | └ index.vue └ resetPassword └ index.vue
這里我們將login作為父組件,讀取服務(wù)端返回的登錄配置并在模板做條件渲染,登錄時調(diào)用子組件內(nèi)部的表單驗證,最后通過Vuex拿到數(shù)據(jù)調(diào)用接口。整個可配置登錄表單的邏輯就是醬子,接下來上代碼。
代碼
請求服務(wù)端配置數(shù)據(jù):
/* 參數(shù)說明:
* 'password': 密碼登錄
* 'captcha': 短信驗證碼登錄
* 'password_or_captcha': 密碼或短信登錄
* 'password_with_captcha': 密碼+短信登錄
*/
config: {
login_methods: 'password'
}
登錄組件的核心渲染代碼(pug):
.login-card .login-header h3 登錄 .login-content phone(ref="phone") password( v-if="isPasswordMode" ref="password" ) captcha( v-if="isCaptchaMode" ref="captcha" ) template(v-if="isPasswordWithCaptchaMode") captcha(ref="captcha") password(ref="password") template(v-if="isPasswordOrCaptchaMode") ... el-button(@click="login") 登錄
登錄時需要三個步驟:表單驗證、組裝數(shù)據(jù)、調(diào)用接口:
async login () {
if (!this.validate()) return
const loginData = this.getLoginData()
await this.postLogin(loginData)
...
}
登錄的表單驗證其實是對當(dāng)前登錄方式中所有組件的 validate() 方法進(jìn)行邏輯判斷:
validate () {
const phone = this.$refs.phone.validate()
let isPass = false
if (this.isPasswordMode) {
if (this.$refs.password) isPass = this.$refs.password.validate()
}
if (this.isCaptchaMode) {
if (this.$refs.captcha) isPass = this.$refs.captcha.validate()
}
if (this.isPasswordWithCaptchaMode) ...
if (this.isPasswordOrCaptchaMode) ...
isPass = phone && isPass
return isPass
}
每個子組件都是一個完整的表單,驗證也由自己完成,password組件模板:
.login-password
el-form(
:model="form"
:rules="rules"
ref="form"
@submit.native.prevent=""
)
el-form-item(prop="password")
el-input(
v-model="form.password"
type="password"
name="password"
)
W3C: When there is only one single-line text input field in a form, the user agent should accept Enter in that field as a request to submit the form.
需要注意,根據(jù) W3C標(biāo)準(zhǔn) , 當(dāng)一個form元素中只有一個輸入框時,在該輸入框中按下回車會自動提交表單。通過在 <el-form> 添加 @submit.native.prevent 可以阻止這一默認(rèn)行為。
password組件的表單驗證:
validate () {
let res = false
this.$refs.form.validate((valid) => {
res = valid
})
return res
}
最后從Vuex里拿到所有表單數(shù)據(jù),進(jìn)行組裝:
computed: {
...mapState('login', {
phone: state => state.phone,
password: state => state.password,
captcha: state => state.captcha
}),
},
methods: {
...
getLoginData () {
let mode = ''
const phone = this.phone
...
const data = { phone }
if (this.isPasswordMode) {
mode = 'password'
data.password = password
}
if (this.isCaptchaMode) {
mode = 'captcha'
data.captcha = captcha
}
if (this.isPasswordWithCaptchaMode) ...
if (this.isPasswordOrCaptchaMode) ...
data.mode = mode
return data
}
}
補(bǔ)充:
vue.js 全選與取消全選的實例代碼
new Vue({
el: '#app',
data: {
checked: false,
checkedNames: [],
checkedArr: ["Runoob", "Taobao", "Google"]
},
methods: {
changeAllChecked: function() {
if (this.checked) {
this.checkedNames = this.checkedArr
} else {
this.checkedNames = []
}
}
},
watch: {
"checkedNames": function() {
if (this.checkedNames.length == this.checkedArr.length) {
this.checked = true
} else {
this.checked = false
}
}
}
})
相關(guān)文章
vue項目打包之開發(fā)環(huán)境和部署環(huán)境的實現(xiàn)
這篇文章主要介紹了vue項目打包之開發(fā)環(huán)境和部署環(huán)境的實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-04-04
淺談vue實現(xiàn)數(shù)據(jù)監(jiān)聽的函數(shù) Object.defineProperty
本篇文章主要介紹了淺談vue實現(xiàn)數(shù)據(jù)監(jiān)聽的函數(shù) Object.defineProperty,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-06-06
vue中監(jiān)聽input框獲取焦點及失去焦點的問題
這篇文章主要介紹了vue中監(jiān)聽input框獲取焦點,失去焦點的問題,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-07-07
vue.js實現(xiàn)含搜索的多種復(fù)選框(附源碼)
這篇文章主要給大家介紹了利用vue.js實現(xiàn)含搜索的多種復(fù)選框的相關(guān)資料,文中給出了簡單的介紹,但提供了完整的實例源碼供大家下載學(xué)習(xí),相信對大家具有一定的參考價值,需要的朋友們下面來一起看看吧。2017-03-03

