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 相关文章推荐
2010年最佳jQuery插件整理
Dec 06 Javascript
JavaScript 验证码的实例代码(附效果图)
Mar 22 Javascript
js实现按Ctrl+Enter发送效果
Sep 18 Javascript
javascript ES6中箭头函数注意细节小结
Feb 17 Javascript
浅谈Vue.js
Mar 02 Javascript
使用jQuery实现一个类似GridView的编辑,更新,取消和删除的功能
Mar 15 Javascript
jQuery中map函数的两种方式
Apr 07 jQuery
JavaScript this绑定过程深入详解
Dec 07 Javascript
简单了解JavaScript异步
May 23 Javascript
使用imba.io框架得到比 vue 快50倍的性能基准
Jun 17 Javascript
Vue-CLI与Vuex使用方法实例分析
Jan 06 Javascript
小程序实现可拖动的悬浮按钮
Sep 07 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中adodbzip类实例
2014/12/08 PHP
php绘图之生成饼状图的方法
2015/01/24 PHP
PHP获取当前日期和时间及格式化方法参数
2015/05/11 PHP
php实现微信原生支付(扫码支付)功能
2018/05/30 PHP
用 JSON 处理缓存
2007/04/27 Javascript
关于javascript 回调函数中变量作用域的讨论
2009/09/11 Javascript
JavaScript小技巧 2.5 则
2010/09/12 Javascript
JS获取网页属性包括宽、高等等
2014/04/03 Javascript
jQuery实现单击弹出Div层窗口效果(可关闭可拖动)
2015/09/19 Javascript
jQuery Form 表单提交插件之formSerialize,fieldSerialize,fieldValue,resetForm,clearForm,clearFields的应用
2016/01/23 Javascript
Node.js Addons翻译(C/C++扩展)
2016/06/12 Javascript
jQuery Validate 无法验证 chosen-select元素的解决方法
2017/05/17 jQuery
js实现鼠标移动到图片产生遮罩效果
2017/10/21 Javascript
Vue 列表上下过渡效果的实例代码
2019/06/25 Javascript
原生js+css实现tab切换功能
2020/09/17 Javascript
nuxt.js服务端渲染中axios和proxy代理的配置操作
2020/11/06 Javascript
[01:34]2014DOTA2展望TI 剑指西雅图VG战队专访
2014/06/30 DOTA
[36:13]Mineski vs iG 2018国际邀请赛小组赛BO2 第一场 8.16
2018/08/17 DOTA
Python中Scrapy爬虫图片处理详解
2017/11/29 Python
用PyInstaller把Python代码打包成单个独立的exe可执行文件
2018/05/26 Python
Python while循环使用else语句代码实例
2020/02/07 Python
python 实现图片修复(可用于去水印)
2020/11/19 Python
HTML5页面无缝闪开的问题及解决方案
2020/06/11 HTML / CSS
马克华菲官方商城:Mark Fairwhale
2016/09/04 全球购物
阿玛瑞酒店中文官方网站:Amari.com
2018/02/13 全球购物
娇韵诗法国官网:Clarins法国
2019/01/29 全球购物
印度领先的眼镜电子商务网站:Lenskart
2019/12/16 全球购物
饭店工作计划书
2014/01/10 职场文书
小学班长竞选演讲稿
2014/04/24 职场文书
超市七夕促销活动方案
2014/08/28 职场文书
公民授权委托书范本
2014/09/17 职场文书
2014年医生工作总结
2014/11/21 职场文书
2015年药房工作总结
2015/04/25 职场文书
社区环境卫生倡议书
2015/04/29 职场文书
课题研究阶段性总结
2015/08/13 职场文书
python中redis包操作数据库的教程
2022/04/19 Python