Vue.js實(shí)現(xiàn)可配置的登錄表單代碼詳解
表單是后臺(tái)項(xiàng)目業(yè)務(wù)中的常用組件,這次重構(gòu)了登錄功能以滿足登錄方式可配置的需求,在此記錄和分享一下。
業(yè)務(wù)場景
在之前,項(xiàng)目只支持手機(jī)號(hào)+密碼登錄,前端是直接把表單寫死的,后來有客戶希望能支持驗(yàn)證碼登錄,有的客戶還希望能有手機(jī)號(hào)+驗(yàn)證碼+密碼的登錄方式…所以登錄方式的靈活性需要可配置的表單支持,于是我把登錄組件做了拆分。
以表單元素為粒度,分離出了手機(jī)號(hào)、密碼、短信驗(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í),在該輸入框中按下回車會(huì)自動(dòng)提交表單。通過在 <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就會(huì)出現(xiàn)div閃現(xiàn),或者部分閃爍的結(jié)果。怎么處理這樣的問題呢,下面小編給大家?guī)砹藇ue使用v-if v-show頁面閃爍,div閃現(xiàn)的解決方法,一起看看吧2018-10-10vue?實(shí)現(xiàn)動(dòng)態(tài)設(shè)置元素的高度
這篇文章主要介紹了在vue中實(shí)現(xiàn)動(dòng)態(tài)設(shè)置元素的高度,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-08-08有關(guān)vue 組件切換,動(dòng)態(tài)組件,組件緩存
這篇文章主要介紹了有關(guān)vue 組件切換,動(dòng)態(tài)組件,組件緩存,在組件化開發(fā)模式下,我們會(huì)把整個(gè)項(xiàng)目拆分成很多組件,然后按照合理的方式組織起來,達(dá)到預(yù)期效果,下面來看看文章的詳細(xì)內(nèi)容2021-11-11vue基于echarts實(shí)現(xiàn)立體柱形圖
這篇文章主要為大家詳細(xì)介紹了vue基于echarts實(shí)現(xiàn)立體柱形圖,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-09-09