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 相关文章推荐
js实现简单模态窗口,背景灰显
Nov 14 Javascript
extjs DataReader、JsonReader、XmlReader的构造方法
Nov 07 Javascript
javascript跑马灯悬停放大效果实现代码
Dec 12 Javascript
如何在node的express中使用socket.io
Dec 15 Javascript
javascript实现获取浏览器版本、操作系统类型
Jan 29 Javascript
浅谈轻量级js模板引擎simplite
Feb 13 Javascript
JS获得图片alt信息的方法
Apr 01 Javascript
详解handlebars+require基本使用方法
Dec 21 Javascript
xmlplus组件设计系列之网格(DataGrid)(10)
May 05 Javascript
jQuery实现广告条滚动效果
Aug 22 jQuery
JavaScript表单即时验证 验证不成功不能提交
Aug 31 Javascript
Vuejs 实现简易 todoList 功能 与 组件实例代码
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
php IP及IP段进行访问限制的代码
2008/12/17 PHP
php set_time_limit(0) 设置程序执行时间的函数
2010/05/26 PHP
php获取网页标题和内容函数(不包含html标签)
2014/02/03 PHP
PHP fopen()和 file_get_contents()应用与差异介绍
2014/03/19 PHP
Zend Framework 2.0事件管理器(The EventManager)入门教程
2014/08/11 PHP
php 数组字符串搜索array_search技巧
2016/07/05 PHP
js几个验证函数代码
2010/03/25 Javascript
关于Javascript 对象(object)的prototype
2014/05/09 Javascript
浅谈jQuery中 wrap() wrapAll() 与 wrapInner()的差异
2014/11/12 Javascript
深入理解JavaScript系列(34):设计模式之命令模式详解
2015/03/03 Javascript
javascript基本包装类型介绍
2015/04/10 Javascript
详细分析使用AngularJS编程中提交表单的方式
2015/06/19 Javascript
浅析AngularJS Filter用法
2015/12/28 Javascript
AngularJS入门教程之链接与图片模板详解
2016/08/19 Javascript
JavaScript之class继承_动力节点Java学院整理
2017/07/03 Javascript
React入门教程之Hello World以及环境搭建详解
2017/07/11 Javascript
Vue 2.0学习笔记之使用$refs访问Vue中的DOM
2017/12/19 Javascript
解决Jquery下拉框数据动态获取的问题
2018/01/25 jQuery
vue element-ui table表格滚动加载方法
2018/03/02 Javascript
简单了解vue中父子组件如何相互传递值(基础向)
2019/07/12 Javascript
Node.js系列之连接DB的方法(3)
2019/08/30 Javascript
vue使用showdown并实现代码区域高亮的示例代码
2019/10/17 Javascript
Node.js API详解之 assert模块用法实例分析
2020/05/26 Javascript
vue中实现点击空白区域关闭弹窗的两种方法
2020/12/30 Vue.js
[35:55]完美世界DOTA2联赛PWL S3 Rebirth vs CPG 第一场 12.11
2020/12/13 DOTA
Python 实现简单的电话本功能
2015/08/09 Python
老生常谈Python基础之字符编码
2017/06/14 Python
python实现冒泡排序算法的两种方法
2018/03/10 Python
python数字图像处理之高级形态学处理
2018/04/27 Python
Python 开发工具通过 agent 代理使用的方法
2020/09/27 Python
Python监听键盘和鼠标事件的示例代码
2020/11/18 Python
大四自我鉴定
2014/02/08 职场文书
大班亲子运动会方案
2014/06/10 职场文书
民族精神月活动总结
2014/08/28 职场文书
MySQL索引 高效获取数据的数据结构
2022/05/02 MySQL
MySQL外键约束(Foreign Key)案例详解
2022/06/28 MySQL