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 Xml增删改查(IE下)操作实现代码
Jan 30 Javascript
javascript正则表达式中参数g(全局)的作用
Nov 11 Javascript
理解javascript正则表达式
Mar 08 Javascript
基于js里调用函数时,函数名带括号和不带括号的区别
Jul 28 Javascript
js实现简单的碰壁反弹效果
Aug 30 Javascript
JavaScript实现通过select标签跳转网页的方法
Sep 29 Javascript
JS奇技之利用scroll来监听resize详解
Jun 15 Javascript
Vue.js 实现微信公众号菜单编辑器功能(一)
May 08 Javascript
JavaScript的词法结构精华篇
Oct 17 Javascript
node+vue实现文件上传功能
May 28 Javascript
Vue + element 实现多选框组并保存已选id集合的示例代码
Jun 03 Javascript
vue-i18n实现中英文切换的方法
Jul 06 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
thinkphp的URL路由规则与配置实例
2014/11/26 PHP
PHP重定向与伪静态区别
2017/02/19 PHP
PHP基于curl实现模拟微信浏览器打开微信链接的方法示例
2019/02/15 PHP
用js得到网页中所有的div的id
2020/10/19 Javascript
javascript 数组的方法集合
2008/06/05 Javascript
解析John Resig Simple JavaScript Inheritance代码
2012/12/03 Javascript
THREE.JS入门教程(6)创建自己的全景图实现步骤
2013/01/25 Javascript
Angular懒加载机制刷新后无法回退的快速解决方法
2016/08/30 Javascript
用jmSlip编写移动端顶部日历选择控件
2016/10/24 Javascript
JS求解三元一次方程组值的方法
2017/01/03 Javascript
关于Vue背景图打包之后访问路径错误问题的解决
2017/11/03 Javascript
IntelliJ IDEA 安装vue开发插件的方法
2017/11/21 Javascript
EasyUI的DataGrid绑定Json数据源的示例代码
2017/12/16 Javascript
Node.js成为Web应用开发最佳选择的原因
2018/02/05 Javascript
python虚拟环境 virtualenv的简单使用
2020/01/21 Javascript
vue开发简单上传图片功能
2020/06/30 Javascript
vue中组件通信详解(父子组件, 爷孙组件, 兄弟组件)
2020/07/27 Javascript
[01:02:26]DOTA2-DPC中国联赛 正赛 SAG vs RNG BO3 第二场 1月18日
2021/03/11 DOTA
简单谈谈Python中的闭包
2016/11/30 Python
详解python脚本自动生成需要文件实例代码
2017/02/04 Python
python selenium自动上传有赞单号的操作方法
2018/07/05 Python
python ftplib模块使用代码实例
2019/12/31 Python
Python SSL证书验证问题解决方案
2020/01/13 Python
TensorFlow基本的常量、变量和运算操作详解
2020/02/03 Python
python GUI编程(Tkinter) 创建子窗口及在窗口上用图片绘图实例
2020/03/04 Python
基于python代码批量处理图片resize
2020/06/04 Python
python 如何实现遗传算法
2020/09/22 Python
pandas 数据类型转换的实现
2020/12/29 Python
html5利用canvas实现颜色容差抠图功能
2019/12/23 HTML / CSS
萨克斯第五大道英国:Saks Fifth Avenue英国
2019/04/01 全球购物
工程概预算专业毕业生求职信
2013/10/04 职场文书
演讲稿的格式及范文
2014/08/22 职场文书
群众路线自查自纠工作情况报告
2014/10/28 职场文书
数学教师个人工作总结
2015/02/06 职场文书
24句精辟的现实社会语录,句句扎心,道尽人性
2019/08/29 职场文书
pandas中关于apply+lambda的应用
2022/02/28 Python