Vue.js實(shí)現(xiàn)可配置的登錄表單代碼詳解
表單是后臺項(xiàng)目業(yè)務(wù)中的常用組件,這次重構(gòu)了登錄功能以滿足登錄方式可配置的需求,在此記錄和分享一下。
業(yè)務(wù)場景
在之前,項(xiàng)目只支持手機(jī)號+密碼登錄,前端是直接把表單寫死的,后來有客戶希望能支持驗(yàn)證碼登錄,有的客戶還希望能有手機(jī)號+驗(yàn)證碼+密碼的登錄方式…所以登錄方式的靈活性需要可配置的表單支持,于是我把登錄組件做了拆分。
以表單元素為粒度,分離出了手機(jī)號、密碼、短信驗(yàn)證碼這幾個(gè)組件,它們內(nèi)部都有自己的表單驗(yàn)證方法,通過組合可以快速完成登錄、注冊、找回密碼等表單組件。高內(nèi)聚低耦合、高內(nèi)聚低耦合…跟著念十遍~
. ├ common ├ captcha.vue | ├ password.vue | └ phone.vue ├ login | └ index.vue ├ register | └ index.vue └ resetPassword └ index.vue
這里我們將login作為父組件,讀取服務(wù)端返回的登錄配置并在模板做條件渲染,登錄時(shí)調(diào)用子組件內(nèi)部的表單驗(yàn)證,最后通過Vuex拿到數(shù)據(jù)調(diào)用接口。整個(gè)可配置登錄表單的邏輯就是醬子,接下來上代碼。
代碼
請求服務(wù)端配置數(shù)據(jù):
/* 參數(shù)說明:
* 'password': 密碼登錄
* 'captcha': 短信驗(yàn)證碼登錄
* '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í)需要三個(gè)步驟:表單驗(yàn)證、組裝數(shù)據(jù)、調(diào)用接口:
async login () {
if (!this.validate()) return
const loginData = this.getLoginData()
await this.postLogin(loginData)
...
}
登錄的表單驗(yàn)證其實(shí)是對當(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
}
每個(gè)子組件都是一個(gè)完整的表單,驗(yàn)證也由自己完成,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)一個(gè)form元素中只有一個(gè)輸入框時(shí),在該輸入框中按下回車會自動提交表單。通過在 <el-form> 添加 @submit.native.prevent 可以阻止這一默認(rèn)行為。
password組件的表單驗(yàn)證:
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 全選與取消全選的實(shí)例代碼
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使用v-if v-show頁面閃爍,div閃現(xiàn)的解決方法
在頁面層次結(jié)構(gòu),數(shù)據(jù)較多的時(shí)候,用v-if或者v-show就會出現(xiàn)div閃現(xiàn),或者部分閃爍的結(jié)果。怎么處理這樣的問題呢,下面小編給大家?guī)砹藇ue使用v-if v-show頁面閃爍,div閃現(xiàn)的解決方法,一起看看吧2018-10-10
vue?實(shí)現(xiàn)動態(tài)設(shè)置元素的高度
這篇文章主要介紹了在vue中實(shí)現(xiàn)動態(tài)設(shè)置元素的高度,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-08-08
有關(guān)vue 組件切換,動態(tài)組件,組件緩存
這篇文章主要介紹了有關(guān)vue 組件切換,動態(tài)組件,組件緩存,在組件化開發(fā)模式下,我們會把整個(gè)項(xiàng)目拆分成很多組件,然后按照合理的方式組織起來,達(dá)到預(yù)期效果,下面來看看文章的詳細(xì)內(nèi)容2021-11-11
vue基于echarts實(shí)現(xiàn)立體柱形圖
這篇文章主要為大家詳細(xì)介紹了vue基于echarts實(shí)現(xiàn)立體柱形圖,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-09-09

