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 相关文章推荐
监控 url fragment变化的js代码
Apr 19 Javascript
避免回车键导致的页面无意义刷新的解决方法
Apr 12 Javascript
JavaScript根据数据生成百分比图和柱状图的实例代码
Jul 14 Javascript
浅析Node.js查找字符串功能
Sep 03 Javascript
jQuery调用ajax请求的常见方法汇总
Mar 24 Javascript
JavaScript中的Math.LOG2E属性使用详解
Jun 14 Javascript
详解微信小程序入门五: wxml文件引用、模版、生命周期
Jan 20 Javascript
React组件之间的通信的实例代码
Jun 27 Javascript
Angular2中监听数据更新的方法
Aug 31 Javascript
Vue.js中 v-model 指令的修饰符详解
Dec 03 Javascript
深入了解JavaScript 私有化
May 30 Javascript
原生javascript自定义input[type=radio]效果示例
Aug 27 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桌面中心(一) 创建数据库
2007/03/11 PHP
PHP的几个常用数字判断函数代码
2012/04/24 PHP
PHP下打开phpMyAdmin出现403错误的问题解决方法
2013/05/23 PHP
php empty()与isset()区别的详细介绍
2013/06/17 PHP
destoon实现调用当前栏目分类及子分类和三级分类的方法
2014/08/21 PHP
php绘图之加载外部图片的方法
2015/01/24 PHP
PHP解析RSS的方法
2015/03/05 PHP
PHP获取客户端及服务器端IP的封装类
2016/07/21 PHP
Thinkphp结合AJAX长轮询实现PC与APP推送详解
2017/07/31 PHP
php5对象复制、clone、浅复制与深复制实例详解
2019/08/14 PHP
表单提交时自动复制内容到剪贴板的js代码
2007/03/16 Javascript
纯Javascript实现Windows 8 Metro风格实现
2013/10/15 Javascript
二叉树的非递归后序遍历算法实例详解
2014/02/07 Javascript
JS实现自动变化的导航菜单效果代码
2015/09/09 Javascript
noty ? jQuery通知插件全面解析
2016/05/18 Javascript
lhgcalendar时间插件限制只能选择三个月的实现方法
2017/07/03 Javascript
小程序开发基础之view视图容器
2018/08/21 Javascript
javascript创建元素和删除元素实例小结
2019/06/19 Javascript
python编写Logistic逻辑回归
2020/12/30 Python
Python可视化mhd格式和raw格式的医学图像并保存的方法
2019/01/24 Python
pymongo中group by的操作方法教程
2019/03/22 Python
Python3将jpg转为pdf文件的方法示例
2019/12/13 Python
Python基础之变量基本用法与进阶详解
2020/01/03 Python
日本一家专门经营各种箱包的大型网站:Traveler Store
2016/08/03 全球购物
有原因的手表:Flex Watches
2019/03/23 全球购物
加拿大的标志性百货公司:Hudson’s Bay(哈得逊湾)
2019/09/03 全球购物
大专毕业生自我评价分享
2013/11/10 职场文书
十八届三中全会个人学习材料
2014/02/13 职场文书
婚假请假条格式及范文
2014/04/10 职场文书
我的理想演讲稿
2014/04/30 职场文书
班组建设经验交流材料
2014/05/12 职场文书
民事申诉状范本
2015/05/20 职场文书
2015高中教师个人工作总结
2015/07/21 职场文书
2015年中学团委工作总结
2015/07/22 职场文书
教你怎么用python selenium实现自动化测试
2021/05/27 Python
node.js使用express-fileupload中间件实现文件上传
2021/07/16 Javascript