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在IE下设置innerHTML时出现未知的运行时错误的解决方法
Jan 12 Javascript
javascript中的=等号个数问题两个跟三个有什么区别
Oct 23 Javascript
jquery绑定事件不生效的解决方法
Feb 11 Javascript
javascript类型系统 Window对象学习笔记
Jan 07 Javascript
JavaScript实现ASC转汉字及汉字转ASC的方法
Jan 23 Javascript
jQuery简单验证上传文件大小及类型的方法
Jun 02 Javascript
JavaScript仿网易选项卡制作代码
Oct 06 Javascript
JavaScript组件开发之输入框加候选框
Mar 10 Javascript
利用js查找数组中指定元素并返回该元素的所有索引示例
Mar 29 Javascript
使用canvas及js简单生成验证码方法
Apr 02 Javascript
关于vuex的学习实践笔记
Apr 05 Javascript
详解vue父子组件状态同步的最佳方式
Sep 10 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
咖啡冲泡指南 咖啡有哪些制作方式 单品咖啡 意式咖啡
2021/03/06 冲泡冲煮
ADODB结合SMARTY使用~超级强
2006/11/25 PHP
php判断访问IP的方法
2015/06/19 PHP
优化WordPress的Google字体以加速国内服务器上的运行
2015/11/24 PHP
通过修改Laravel Auth使用salt和password进行认证用户详解
2017/08/17 PHP
基于JQuery的模拟苹果桌面Dock效果(稳定版)
2012/10/15 Javascript
Jquery多选框互相内容交换的实例代码
2013/07/04 Javascript
JS实现静止元素自动移动示例
2014/04/14 Javascript
setTimeout()递归调用不加引号出错的解决方法
2014/09/05 Javascript
javascript中typeof操作符和constucor属性检测
2015/02/26 Javascript
JavaScript获取网页中第一个链接ID的方法
2015/04/03 Javascript
javascript操作表格排序实例分析
2015/05/06 Javascript
基于insertBefore制作简单的循环插空效果
2015/09/21 Javascript
jQuery中hover与mouseover和mouseout的区别分析
2015/12/24 Javascript
jQuery实现立体式数字滚动条增加效果
2016/12/21 Javascript
Node之简单的前后端交互(实例讲解)
2017/11/14 Javascript
vue 简单自动补全的输入框的示例
2018/03/12 Javascript
微信小程序中实现手指缩放图片的示例代码
2018/03/13 Javascript
纯javascript前端实现base64图片下载(兼容IE10+)
2018/09/14 Javascript
微信小程序 slot踩坑的解决
2019/04/01 Javascript
小程序click-scroll组件设计
2019/06/18 Javascript
vue 自动化路由实现代码
2019/09/03 Javascript
JavaScript实现拖拽效果
2020/03/16 Javascript
使用Vant完成DatetimePicker 日期的选择器操作
2020/11/12 Javascript
删除目录下相同文件的python代码(逐级优化)
2012/05/25 Python
python通过urllib2获取带有中文参数url内容的方法
2015/03/13 Python
Python抓取百度查询结果的方法
2015/07/08 Python
python中requests小技巧
2017/05/10 Python
Python 十六进制整数与ASCii编码字符串相互转换方法
2018/07/09 Python
pytorch逐元素比较tensor大小实例
2020/01/03 Python
pytorch中的上采样以及各种反操作,求逆操作详解
2020/01/03 Python
Python装饰器原理与基本用法分析
2020/01/07 Python
python GUI库图形界面开发之PyQt5简单绘图板实例与代码分析
2020/03/08 Python
世界最大的私人旅行指南出版商:孤独星球
2016/08/23 全球购物
Shopty西班牙:缝纫机在线销售
2018/01/26 全球购物
高中军训感言800字
2014/03/05 职场文书