Vue.js实现可配置的登录表单代码详解


Posted in Javascript onMarch 29, 2018

表单是后台项目业务中的常用组件,这次重构了登录功能以满足登录方式可配置的需求,在此记录和分享一下。

业务场景

在之前,项目只支持手机号+密码登录,前端是直接把表单写死的,后来有客户希望能支持验证码登录,有的客户还希望能有手机号+验证码+密码的登录方式…所以登录方式的灵活性需要可配置的表单支持,于是我把登录组件做了拆分。

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
      }
    }
  }
})
Javascript 相关文章推荐
用户注册常用javascript代码
Aug 29 Javascript
js获取当前月的第一天和最后一天的小例子
Nov 18 Javascript
Jquery实现的一种常用高亮效果示例代码
Jan 28 Javascript
Jquery图片延迟加载插件jquery.lazyload.js的使用方法
May 21 Javascript
JavaScript的类型、值和变量小结
Jul 09 Javascript
JS实现把鼠标放到链接上出现滚动文字的方法
Apr 06 Javascript
终于实现了!精彩的jquery弹幕效果
Jul 18 Javascript
郁闷!ionic中获取ng-model绑定的值为undefined如何解决
Aug 27 Javascript
详解基于DllPlugin和DllReferencePlugin的webpack构建优化
Jun 28 Javascript
react项目实践之webpack-dev-serve
Sep 14 Javascript
elementUI多选框反选的实现代码
Apr 03 Javascript
Javascript原生ajax请求代码实例
Feb 20 Javascript
Vue项目中如何引入icon图标
Mar 28 #Javascript
JavaScript中的E-mail 地址格式验证
Mar 28 #Javascript
javascript性能优化之分时函数的介绍
Mar 28 #Javascript
Vue数据监听方法watch的使用
Mar 28 #Javascript
Vue 自定义动态组件实例详解
Mar 28 #Javascript
详解VUE 对element-ui中的ElTableColumn扩展
Mar 28 #Javascript
微信小程序之分享页面如何返回首页的示例
Mar 28 #Javascript
You might like
tp5框架内使用tp3.2分页的方法分析
2019/05/05 PHP
与jquery serializeArray()一起使用的函数,主要来方便提交表单
2011/01/31 Javascript
jquery得到iframe src属性值的方法
2014/09/25 Javascript
jQuery实现鼠标经过时出现隐藏层文字链接的方法
2015/10/12 Javascript
jQuery实现进度条效果代码
2015/12/17 Javascript
Bootstrap框架实现广告轮播效果
2016/11/28 Javascript
详谈构造函数加括号与不加括号的区别
2017/10/26 Javascript
基于jQuery实现无缝轮播与左右点击效果
2018/05/13 jQuery
jQuery实现的点击显示隐藏下拉菜单功能完整示例
2019/05/17 jQuery
js变量值传到php过程详解 将php解析成数据
2019/06/26 Javascript
解决layui轮播图有数据不显示的情况
2019/09/16 Javascript
[02:09]EHOME夺得首届辉夜杯冠军—现场颁奖仪式
2015/12/28 DOTA
用Python从零实现贝叶斯分类器的机器学习的教程
2015/03/31 Python
python使用分治法实现求解最大值的方法
2015/05/12 Python
python处理二进制数据的方法
2015/06/03 Python
python去掉行尾的换行符方法
2017/01/04 Python
Python探索之URL Dispatcher实例详解
2017/10/28 Python
python中闭包Closure函数作为返回值的方法示例
2017/12/17 Python
Django REST为文件属性输出完整URL的方法
2017/12/18 Python
浅谈python中np.array的shape( ,)与( ,1)的区别
2018/06/04 Python
详解TensorFlow查看ckpt中变量的几种方法
2018/06/19 Python
python处理multipart/form-data的请求方法
2018/12/26 Python
python使用参数对嵌套字典进行取值的方法
2019/04/26 Python
详解Canvas事件绑定
2018/06/27 HTML / CSS
HTML5上传文件显示进度的实现代码
2012/08/30 HTML / CSS
中国领先的专业演出票务网:永乐票务
2016/08/29 全球购物
曼联官方网上商店:Manchester United Direct
2017/07/28 全球购物
澳大利亚手表品牌:Time IV Change
2018/10/06 全球购物
财务部总监岗位职责
2014/03/12 职场文书
环保建议书100字
2014/05/14 职场文书
药剂专业自荐书
2014/06/20 职场文书
2014年教师节活动总结
2014/08/29 职场文书
毕业生班级鉴定评语
2015/01/04 职场文书
年会主持人开场白台词
2015/05/29 职场文书
golang日志包logger的用法详解
2021/05/05 Golang
Pytorch中expand()的使用(扩展某个维度)
2022/07/15 Python