Vue.js实现可配置的登录表单代码详解
表单是后台项目业务中的常用组件,这次重构了登录功能以满足登录方式可配置的需求,在此记录和分享一下。
业务场景
在之前,项目只支持手机号+密码登录,前端是直接把表单写死的,后来有客户希望能支持验证码登录,有的客户还希望能有手机号+验证码+密码的登录方式…所以登录方式的灵活性需要可配置的表单支持,于是我把登录组件做了拆分。
以表单元素为粒度,分离出了手机号、密码、短信验证码这几个组件,它们内部都有自己的表单验证方法,通过组合可以快速完成登录、注册、找回密码等表单组件。高内聚低耦合、高内聚低耦合…跟着念十遍~
. ├ common ├ captcha.vue | ├ password.vue | └ phone.vue ├ login | └ index.vue ├ register | └ index.vue └ resetpassword └ index.vue
这里我们将login作为父组件,读取服务端返回的登录配置并在模板做条件渲染,登录时调用子组件内部的表单验证,最后通过vuex拿到数据调用接口。整个可配置登录表单的逻辑就是酱子,接下来上代码。
代码
请求服务端配置数据:
/* 参数说明: * '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") 登录
登录时需要三个步骤:表单验证、组装数据、调用接口:
async login () { if (!this.validate()) return const logindata = this.getlogindata() await this.postlogin(logindata) ... }
登录的表单验证其实是对当前登录方式中所有组件的 validate() 方法进行逻辑判断:
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.
需要注意,根据 w3c标准 , 当一个form元素中只有一个输入框时,在该输入框中按下回车会自动提交表单。通过在 <el-form> 添加 @submit.native.prevent 可以阻止这一默认行为。
password组件的表单验证:
validate () { let res = false this.$refs.form.validate((valid) => { res = valid }) return res }
最后从vuex里拿到所有表单数据,进行组装:
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 } }
补充:
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 } } } })
上一篇: 网站推广软文的三种推广技巧
下一篇: 使用Vue制作图片轮播组件思路详解