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 动态改变图片大小
Jun 11 Javascript
基于jquery的3d效果实现代码
Mar 23 Javascript
通过JS获取用户本地图片路径并显示的代码
Feb 16 Javascript
js QQ客服悬浮效果实现代码
Dec 12 Javascript
jQuery判断对象是否存在的方法
Feb 05 Javascript
jQuery+slidereveal实现的面板滑动侧边展出效果
Mar 14 Javascript
jQuery使用$.get()方法从服务器文件载入数据实例
Mar 25 Javascript
javascript中一些util方法汇总
Jun 10 Javascript
jQuery插件Validation快速完成表单验证的方式
Jul 28 Javascript
如何解决IONIC页面底部被遮住无法向上滚动问题
Sep 06 Javascript
yii form 表单提交之前JS在提交按钮的验证方法
Mar 15 Javascript
vue移动UI框架滑动加载数据的方法
Mar 12 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解析html的实现代码
2011/08/08 PHP
解析php session_set_save_handler 函数的用法(mysql)
2013/06/29 PHP
浅析php插件 Simple HTML DOM 用DOM方式处理HTML
2013/07/01 PHP
php函数间的参数传递(值传递/引用传递)
2013/09/23 PHP
php 模拟post_验证页面的返回状态(实例讲解)
2013/10/28 PHP
浅谈ThinkPHP5.0版本和ThinkPHP3.2版本的区别
2017/06/17 PHP
javascript(jquery)利用函数修改全局变量的代码
2009/11/02 Javascript
js 小数取整的函数
2010/05/10 Javascript
Javascript引用指针使用介绍
2012/11/07 Javascript
JS Map 和 List 的简单实现代码
2013/07/08 Javascript
深入理解JavaScript系列(34):设计模式之命令模式详解
2015/03/03 Javascript
JavaScript中的getTime()方法使用详解
2015/06/10 Javascript
快速掌握WordPress中加载JavaScript脚本的方法
2015/12/17 Javascript
JavaScript 数组- Array的方法总结(推荐)
2016/07/21 Javascript
js实现数字递增特效【仿支付宝我的财富】
2017/05/05 Javascript
JavaScript多线程运行库Nexus.js详解
2017/12/22 Javascript
vue.js动画中的js钩子函数的实现
2018/07/06 Javascript
深入理解js A*寻路算法原理与具体实现过程
2018/12/13 Javascript
vue-cli3 项目优化之通过 node 自动生成组件模板 generate View、Component
2019/04/30 Javascript
Python查看多台服务器进程的脚本分享
2014/06/11 Python
利用Fn.py库在Python中进行函数式编程
2015/04/22 Python
Python脚本判断 Linux 是否运行在虚拟机上
2015/04/25 Python
在Python程序中实现分布式进程的教程
2015/04/28 Python
Python 利用pydub库操作音频文件的方法
2019/01/09 Python
Python魔法方法功能与用法简介
2019/04/04 Python
Python脚本破解压缩文件口令实例教程(zipfile)
2020/06/14 Python
猎人靴英国官网:Hunter Boots
2017/02/02 全球购物
美国林业供应商:Forestry Suppliers
2019/05/01 全球购物
linux面试题参考答案(5)
2014/09/01 面试题
岗位职责定义及内容
2013/11/08 职场文书
全国道德模范事迹
2014/02/01 职场文书
消防安全管理制度
2014/02/01 职场文书
学习十八大报告感言
2014/02/28 职场文书
小学生常见病防治方案
2014/06/06 职场文书
干货:如何写好观后感 !
2019/05/21 职场文书
js之ajax文件上传
2021/05/13 Javascript