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 相关文章推荐
js 模拟实现类似c#下的hashtable的简单功能代码
Jan 24 Javascript
jQuery拖动图片删除示例
May 10 Javascript
js实现正方形颜色从下往上升的效果
Aug 04 Javascript
JS+CSS实现仿触屏手机拨号盘界面及功能模拟完整实例
May 16 Javascript
jquery判断类型是不是number类型的实例代码
Oct 07 Javascript
浅析如何利用angular结合translate为项目实现国际化
Dec 08 Javascript
webpack打包单页面如何引用的js
Jun 07 Javascript
JS+HTML5 FileReader实现文件上传前本地预览功能
Mar 27 Javascript
js 获取html5的data属性实现方法
Jul 28 Javascript
vue canvas绘制矩形并解决由clearRec带来的闪屏问题
Sep 02 Javascript
javascript实现摄像头拍照预览
Sep 30 Javascript
JS实现长图上下滚动效果
Mar 19 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技巧与注意事项分析
2011/02/03 PHP
php删除页面记录 同时刷新页面 删除条件用GET方式获得
2012/01/10 PHP
php中数组首字符过滤功能代码
2012/07/31 PHP
php简单统计字符串单词数量的方法
2015/06/19 PHP
PHP的mysqli_thread_id()函数讲解
2019/01/24 PHP
动态读取JSON解析键值对的方法
2014/06/03 Javascript
javascript事件冒泡和事件捕获详解
2015/05/26 Javascript
在JavaScript中使用NaN值的方法
2015/06/05 Javascript
JS声明式函数与赋值式函数实例分析
2016/12/13 Javascript
详谈$.data()的用法和作用
2017/02/13 Javascript
ES6学习教程之对象字面量详解
2017/10/09 Javascript
原生JS实现的多个彩色小球跟随鼠标移动动画效果示例
2018/02/01 Javascript
vue使用jsonp抓取qq音乐数据的方法
2018/06/21 Javascript
angular4中*ngFor不能对返回来的对象进行循环的解决方法
2018/09/12 Javascript
使用FormData实现上传多个文件
2018/12/04 Javascript
node.js中ws模块创建服务端和客户端,网页WebSocket客户端
2019/03/06 Javascript
typescript nodejs 依赖注入实现方法代码详解
2019/07/21 NodeJs
element-ui 文件上传修改文件名的方法示例
2019/11/05 Javascript
微信小程序webSocket的使用方法
2020/02/20 Javascript
vue elementui tree 任意级别拖拽功能代码
2020/08/31 Javascript
Python中模块pymysql查询结果后如何获取字段列表
2017/06/05 Python
Python利用公共键如何对字典列表进行排序详解
2018/05/19 Python
使用Python获取网段IP个数以及地址清单的方法
2018/11/01 Python
python中实现控制小数点位数的方法
2019/01/24 Python
Python多线程处理实例详解【单进程/多进程】
2019/01/30 Python
Python实现的企业粉丝抽奖功能示例
2019/07/26 Python
Python使用requests xpath 并开启多线程爬取西刺代理ip实例
2020/03/06 Python
Django 自定义权限管理系统详解(通过中间件认证)
2020/03/11 Python
使用Nibabel库对nii格式图像的读写操作
2020/07/01 Python
Python如何输出百分比
2020/07/31 Python
捷克多品牌在线时尚商店:ANSWEAR.cz
2020/10/03 全球购物
生日宴会答谢词
2014/01/09 职场文书
大学新生欢迎词
2014/01/10 职场文书
干部行政关系介绍信
2014/01/17 职场文书
会计师事务所实习证明
2014/11/16 职场文书
小学体育跳绳课教学反思
2016/02/16 职场文书