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 相关文章推荐
jquery下onpropertychange事件的绑定方法
Aug 01 Javascript
JavaScript词法作用域与调用对象深入理解
Nov 29 Javascript
checkbox全选所涉及到的知识点介绍
Dec 31 Javascript
js原型继承的两种方法对比介绍
Mar 30 Javascript
javascript获取当前的时间戳的方法汇总
Jul 26 Javascript
js实现各种复制到剪贴板的方法(分享)
Oct 27 Javascript
Dropzone.js实现文件拖拽上传功能(附源码下载)
Nov 22 Javascript
JS中setTimeout和setInterval的最大延时值详解
Feb 13 Javascript
Vue-Router进阶之滚动行为详解
Sep 13 Javascript
jquery获取元素到屏幕四周可视距离的方法
Sep 05 jQuery
基于vue-cli3和element实现登陆页面
Nov 13 Javascript
使用Vue 自定义文件选择器组件的实例代码
Mar 04 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如何写APP接口详解
2016/08/23 PHP
PHP PDO和消息队列的个人理解与应用实例分析
2019/11/25 PHP
JS实现浏览器菜单命令
2006/09/05 Javascript
JQuery EasyUI 对话框的使用方法
2010/10/24 Javascript
js使用split函数按照多个字符对字符串进行分割的方法
2015/03/20 Javascript
js实现可控制左右方向的无缝滚动效果
2016/05/29 Javascript
JS判断字符串变量是否含有某个字串的实现方法
2016/06/03 Javascript
网页瀑布流布局jQuery实现代码
2016/10/21 Javascript
AngularJS使用angular.bootstrap完成模块手动加载的方法分析
2017/01/19 Javascript
vue.js的提示组件
2017/03/02 Javascript
vue图片加载与显示默认图片实例代码
2017/03/16 Javascript
JavaScript中的return布尔值的用法和原理解析
2017/08/14 Javascript
Vue实现导航栏点击当前标签变色功能
2020/08/19 Javascript
JS实现音乐导航特效
2020/01/06 Javascript
python学习之第三方包安装方法(两种方法)
2015/07/30 Python
Python语言生成水仙花数代码示例
2017/12/18 Python
Python加载带有注释的Json文件实例
2018/05/23 Python
Django实现支付宝付款和微信支付的示例代码
2018/07/25 Python
python多线程抽象编程模型详解
2019/03/20 Python
Python二维码生成识别实例详解
2019/07/16 Python
Django 请求Request的具体使用方法
2019/11/11 Python
python中导入 train_test_split提示错误的解决
2020/06/19 Python
使用Python中tkinter库简单gui界面制作及打包成exe的操作方法(二)
2020/10/12 Python
HTML5 常用语法一览(列举不支持的属性)
2010/01/26 HTML / CSS
古驰英国官网:GUCCI英国
2020/03/07 全球购物
简述synchronized和java.util.concurrent.locks.Lock的异同
2014/12/08 面试题
数据库设计的包括哪两种,请分别进行说明
2016/07/15 面试题
最新销售员个人自荐信
2013/09/21 职场文书
毕业生造价工程师求职信
2013/10/17 职场文书
勾股定理课后反思
2014/04/26 职场文书
优秀毕业生自荐信
2014/06/10 职场文书
毕业生找工作自荐书
2014/06/30 职场文书
社区党建工作总结2015
2015/05/13 职场文书
七一表彰大会简报
2015/07/20 职场文书
2016暑期社会实践新闻稿
2015/11/25 职场文书
详解nginx.conf 中 root 目录设置问题
2021/04/01 Servers