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 相关文章推荐
ASP Json Parser修正版
Dec 06 Javascript
获取表单控件原始(初始)值的方法
Aug 21 Javascript
js类式继承的具体实现方法
Dec 31 Javascript
Egret引擎开发指南之视觉编程
Sep 03 Javascript
jquery预加载图片的方法
May 27 Javascript
jQuery取消ajax请求的方法
Jun 09 Javascript
Angular 容器部署的方法
Apr 17 Javascript
Bootstrap 时间日历插件bootstrap-datetimepicker配置与应用小结
May 28 Javascript
nodemon实现Typescript项目热更新的示例代码
Nov 19 Javascript
超简单的微信小程序轮播图
Nov 22 Javascript
如何利用JavaScript编写一个格斗小游戏
Jan 06 Javascript
vue响应式原理与双向数据的深入解析
Jun 04 Vue.js
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 mysql获取表字段名称和字段信息的三种方法
2016/11/13 PHP
Javascript 面向对象(二)封装代码
2012/05/23 Javascript
JS动态添加option和删除option(附实例代码)
2013/04/01 Javascript
js之事件冒泡和事件捕获详细介绍
2013/10/28 Javascript
js实现TAB切换对应不同颜色的代码
2015/08/31 Javascript
深入剖析JavaScript:Object类型
2016/05/10 Javascript
jQuery插件学习教程之SlidesJs轮播+Validation验证
2016/07/12 Javascript
jquery计算出left和top,让一个div水平垂直居中的简单实例
2016/07/13 Javascript
es6的数字处理的方法(5个)
2017/03/16 Javascript
js实现不提示直接关闭网页窗口
2017/03/30 Javascript
老生常谈angularjs中的$state.go
2017/04/24 Javascript
JS实现图片手风琴效果
2020/04/17 Javascript
vuex的使用及持久化state的方式详解
2018/01/23 Javascript
总结JavaScript在IE9之前版本中内存泄露问题
2018/04/28 Javascript
使用layui 渲染table数据表格的实例代码
2018/08/19 Javascript
JS实现百度网盘任意文件强制下载功能
2018/08/31 Javascript
vscode下vue项目中eslint的使用方法
2019/01/13 Javascript
Jquery遍历筛选数组的几种方法和遍历解析json对象,Map()方法详解以及数组中查询某值是否存在
2019/01/18 jQuery
Vue中添加滚动事件设置的方法详解
2020/09/14 Javascript
python中安装模块包版本冲突问题的解决
2017/05/02 Python
Pandas操作CSV文件的读写实现方法
2019/11/13 Python
pytorch: Parameter 的数据结构实例
2019/12/31 Python
Python数据结构dict常用操作代码实例
2020/03/12 Python
python基于socket函数实现端口扫描
2020/05/28 Python
浅析Python 多行匹配模式
2020/07/24 Python
python实现scrapy爬虫每天定时抓取数据的示例代码
2021/01/27 Python
html5 更新图片颜色示例代码
2014/07/29 HTML / CSS
战略合作协议书范本
2014/04/18 职场文书
工作评语大全
2014/04/26 职场文书
社区两委对照检查材料
2014/08/23 职场文书
单位考核聘任报告
2015/03/02 职场文书
html5移动端禁止长按图片保存的实现
2021/04/20 HTML / CSS
如何理解Vue简单状态管理之store模式
2021/05/15 Vue.js
java后台调用接口及处理跨域问题的解决
2022/03/24 Java/Android
详解Android中的TimePickerView(时间选择器)的用法
2022/04/30 Java/Android
Python TypeError: ‘float‘ object is not subscriptable错误解决
2022/12/24 Python