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实现的动态添加表单元素input,button等(appendChild)
Nov 24 Javascript
JQuery文本框高亮显示插件代码
Apr 02 Javascript
Shell脚本实现Linux系统和进程资源监控
Mar 05 Javascript
深入理解JavaScript中的对象
Jun 04 Javascript
jQuery实现延迟跳转的方法
Jun 05 Javascript
jQuery动态修改字体大小的方法【测试可用】
Sep 09 Javascript
Javascript实现从小到大的数组转换成二叉搜索树
Jun 13 Javascript
移动设备手势事件库Touch.js使用详解
Aug 18 Javascript
微信小程序实现tab切换效果
Nov 21 Javascript
vue实现登录页面的验证码以及验证过程解析(面向新手)
Aug 02 Javascript
解决vue页面刷新,数据丢失的问题
Nov 24 Vue.js
Javascript生成器(Generator)的介绍与使用
Jan 31 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
配置支持SSI
2006/11/25 PHP
PHP开发工具ZendStudio下Xdebug工具使用说明详解
2013/11/11 PHP
PHP生成唯一订单号的方法汇总
2015/04/16 PHP
PHP实现简单搜歌的方法
2015/07/28 PHP
PHP获取昨天、今天及明天日期的方法
2016/02/03 PHP
jquery及原生js获取select下拉框选中的值示例
2013/10/25 Javascript
javascript 通用loading动画效果实例代码
2014/01/14 Javascript
基于JQuery和CSS3实现仿Apple TV海报背景视觉差特效源码分享
2015/09/21 Javascript
理解Javascript的call、apply
2015/12/16 Javascript
基于javascript实现动态显示当前系统时间
2016/01/28 Javascript
javascript禁止超链接跳转的方法
2016/02/02 Javascript
javascript绘制漂亮的心型线效果完整实例
2016/02/02 Javascript
百度地图JavascriptApi Marker平滑移动及车头指向行径方向
2017/03/13 Javascript
使用node.js搭建服务器
2017/05/20 Javascript
详解vue前后台数据交互vue-resource文档
2017/07/19 Javascript
详解HTML5 使用video标签实现选择摄像头功能
2017/10/25 Javascript
微信小程序的部署方法步骤
2018/09/04 Javascript
浅谈VUE防抖与节流的最佳解决方案(函数式组件)
2019/05/22 Javascript
微信小程序之 catalog 切换实现解析
2019/09/12 Javascript
[43:35]EG vs Winstrike 2018国际邀请赛小组赛BO2 第一场 8.18
2018/08/19 DOTA
Python如何快速上手? 快速掌握一门新语言的方法
2017/11/14 Python
python实现俄罗斯方块
2018/06/26 Python
详解Django解决ajax跨域访问问题
2018/08/24 Python
Python基础学习之基本数据结构详解【数字、字符串、列表、元组、集合、字典】
2019/06/18 Python
python中adb有什么功能
2020/06/07 Python
详解python算法常用技巧与内置库
2020/10/17 Python
Django自定义YamlField实现过程解析
2020/11/11 Python
css3中的calc函数浅析
2018/07/10 HTML / CSS
调用HTML5的Canvas API绘制图形的快速入门指南
2016/06/17 HTML / CSS
过滤器的用法
2013/10/08 面试题
医院护理人员的自我评价分享
2013/10/04 职场文书
2016年小学优秀班主任事迹材料
2016/02/29 职场文书
公司会议开幕词
2016/03/03 职场文书
2019年思想汇报
2019/06/20 职场文书
React中的Context应用场景分析
2021/06/11 Javascript
Node.js实现断点续传
2021/06/23 Javascript