准备工作

  • 使用Vue-cli构建的单页面组件
  • 使用vrouter进行登录和注册页面转换
  • 使用Element-ui 实现布局和UI

布局

Element-ui使用栅格布局,在此直接复制布局代码。
复制代码如下:

<div id="rooter">
        <el-row>
            <el-col :span="24">
                <div class="grid-content bg-purple-dark"></div>
            </el-col>
        </el-row>
        <el-row :gutter="20">
            <el-col :span="10">
                <div class="grid-content bg-purple"></div>
            </el-col>
            <el-col :span="10">
                <div class="grid-content bg-purple-light"></div>
            </el-col>
        </el-row>
    </div>

Element-ui的栅格是一行24列,<el-row> 代表行,<el-col> 代表列

其中 gutter 属性代表栅格间的间距(槽)默认为0,不写即可; span 属性代表每一列占据栅格的数量, offset 属性代表偏移栅格的数量

elemenui栅格布局 element ui 栅格_ui

注册界面容器

这里我用 <el-card> 来实现注册所在的位置,引入element-ui的代码。为了和登录页面联动,我添加了路由并修改了布局的一些细节,代码如下:

<div id="rooter">
    <el-row > 
        <el-col :span="24">
            <div class="grid-content"></div>
            <!--在style中设置高度-->
        </el-col>
    </el-row>
    <el-row>
        <el-col :span="8" :offset="8">
            <el-card shadow="always">
                <el-button type="text" @click="gotologin">登录</el-button>
                <el-button type="text" @click="gotologon">注册</el-button>
                <el-divider></el-divider>
            </el-card>
        </el-col>
    </el-row>
</div>
...
 methods: {
        gotologin(){
            this.$router.push({name:'login'})
        },
        gotologon(){
            this.$router.push({name:'logon'})
        }
    }
...
.grid-content {
    min-height: 100px;
}

效果如下:

elemenui栅格布局 element ui 栅格_elemenui栅格布局_02


ps: 残影是因为录屏软件的原因。

注册主要功能的实现

实现注册需要使用表单来完成,在此提出五个注册时必须的字段:

  1. 用户名,可以验证唯一性
  2. 邮箱或者手机号,用来发送验证码
  3. 验证码
  4. 密码
  5. 确认密码

当然,后端的逻辑我还不会写。但需要确保邮箱或手机号的格式正确以及两次密码要一致。

UI的搭建

引入element-ui的表单 表单项 输入框 按钮这些组件,把大概的样子写出来。
代码如下:

<el-form label-position="right">
    <el-form-item label="用户名">
          <el-input></el-input>
      </el-form-item>
      <el-form-item label="账号">
          <el-input></el-input>
      </el-form-item>
      <el-form-item label="验证码">
          <el-col span="10" push="1">
              <el-input></el-input>
          </el-col>
          <el-col span="9" push="2">
              <el-button type="primary">发送验证码</el-button>
          </el-col>
      </el-form-item>
      <el-form-item label="密码">
          <el-input></el-input>
      </el-form-item>
      <el-form-item label="确认密码">
          <el-input></el-input>
      </el-form-item>
</el-form>

elemenui栅格布局 element ui 栅格_验证码_03

数据接收

使用v-mov-model双向绑定,将各个输入框的数据收集起来。

<el-form 
   label-position="right" 
    :model="register">

    <el-form-item label="用户名">
        <el-input 
            v-model="register.userName"
            placeholder="字母及数字,区分大小写"></el-input>
    </el-form-item>

    <el-form-item label="账号">
        <el-input 
            v-model="register.account"
            placeholder="输入手机号或邮箱"></el-input>
    </el-form-item>
    
    <el-form-item label="验证码">
        <el-col span="10" push="1">
            <el-input 
                v-model="register.identifyCode"
                placeholder="四位验证码"></el-input>
        </el-col>
        <el-col span="9" push="2">
            <el-button type="success">发送验证码</el-button>
        </el-col>
    </el-form-item>
    
    <el-form-item label="密码">
     <!--写上type类型可以减少条件匹配-->
        <el-input
        	type="password"
        	show-password
            v-model="register.password"
            placeholder="6至12位字母、符号和数字"></el-input>
    </el-form-item>
    
    <el-form-item label="确认密码">
        <el-input 
        	type="password"
        	show-password
            v-model="register.checkPassword"
            placeholder="请重复输入密码"></el-input>
    </el-form-item>
</el-form>
...
data() {
  return {
        register: {
            userName: '',
            account: '',
            identifyCode: '',
            password: '',
            checkPassword: ''
        }
    }
},

el-form 表单上使用 :model 来绑定整个表单的对象,内部的el-form-itemel-input 上用 v-model 绑定对象的具体属性值。

添加表单条件判断

实现表单条件判断需要三步:
第一步,在 el-form 上添加rule 对象
第二步,在每个 el-form-item 上添加对应的匹配规则
第三步, 在data函数的 return 中 添加 匹配对象和每个匹配对象的规则
规则的判断是同步的,同是有三个判断规则时,三个判断不分先后。
el-from的一些属性 :model form表单的数据对象 :rules form表单的验证规则对象 这两个是element-ui所定义的属性,都是需要验证时才写。 :ref vue中的属性,用来获取所在的元素信息。

用户名和账户验证

用户名的验证规则是 以字母开头,只包含字母和数字;
账号的验证规则是 输入手机号和邮箱,确保格式正确

<el-form 
   label-position="right" 
    :model="register"
    :rules="registerRules"
    :ref="registerFrom">

    <el-form-item 
        label="用户名"
        prop="userName">
        <el-input 
            v-model="register.userName"
            placeholder="字母开头可以包含数字,区分大小写"></el-input>
    </el-form-item>

    <el-form-item 
        label="账号"
        prop="account">
        <el-input 
            v-model="register.account"
            placeholder="输入手机号或邮箱"></el-input>
    </el-form-item>
···
data() {
    let checkunique = (rule, value, callback)=>{
         setTimeout(() => {  //模拟后端检测过程
             if(!value){
                 callback(new Error('该用户名已被注册'));
             } else {
                 callback()
             }
         }, 1000);
         
     }
     let checkacccount = (rule, value, callback) => {
         let regEmail = /[\w]+(\.[\w]+)*@[\w]+(\.[\w])+/
         let regPhone = /^1(3[0-9]|5[0-3,5-9]|7[1-3,5-8]|8[0-9])\d{8}$/
         if(regEmail.test(value)){
             callback()
         } else if(regPhone.test(value)){
             callback()
         } else {
             callback(new Error('请输入正确的邮箱或电话号码格式'))
         }
     }
     return {
         register: {
             userName: '',
             account: '',
             identifyCode: '',
             password: '',
             checkPassword: ''
         },
         registerRules: {
             userName: [
                 {required: true, message: '请输入用户名', tigger: 'blur'},
                 {pattern: /^(?![0-9])[0-9A-Za-z]{0,12}$/,
                 message:'由字母开头',
                 tigger: 'blur'},
                 {pattern: /^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{4,12}$/,
                 message:'由字母和数字组成,4-12个字符',
                 tigger: 'blur'},
                 {validator: checkunique, tigger:'blur'}],
             account: [
                 {required: true, message: '请输入邮箱或电话号码', tigger: 'blur'},
                 {validator: checkacccount, tigger:'blur'}
             ]
         }
     }
 },

按照三步走的方法,先在表单上添加rule验证规则;包括在 el-form上添加 :rule 在 el-form-item上添加prop用来验证具体的规则。
随后在data() 函数中添加 rule规则 包含在return 中。
验证规则是一个配置对象,单独的验证规则项是一个数组,数组中包含多个对象。
一个对象代表一条规则,常用的对象属性有 :

属性名

作用

required

是否位必须

message

不满足时提示信息

tigger

触发条件

pattern

正则表达式

validator

另写匹配函数

验证用户名

用户名的验证比较简单,直接配置rule即可,第一条用来匹配用户名是必填的,第二条用正则表达式匹配由字母开头包含字母和数字及长度。

验证账户

因为账户可以是邮箱或者手机号,如果用rule配置对象,则两者不能都满足,所以用自定义匹配属性写。
自定义匹配属性 包含一个回调函数,回调函数接收三个参数,rule 是 目前匹配的规则,value是input输入框输入的内容,callback是该匹配规则的回调函数。
文中用两条正则进行验证。

验证密码

需要验证两次密码输入一致,element-ui中有些相关逻辑,我用的也是其中的方法。

...
	<el-form-item 
		label="密码"
		prop="password">
			<el-input 
			   type="password"
			   show-password
			   v-model="register.password"
			   placeholder="6至12位字母、符号和数字"></el-input>
	</el-form-item>
		
	<el-form-item 
		label="确认密码"
		prop="checkPassword">
		<!-- 记得写type类型 -->
			<el-input 
			   type="password" 
			   show-password
			   v-model="register.checkPassword"
			   placeholder="请重复输入密码"></el-input>
	</el-form-item>
...
data(){
	 let password = (rule, value, callback) => {
            if (value.length < 6 || value.length>12){
                callback(new Error('密码长度在6至12位'))
            } else { 
                if(this.register.checkPassword !== ''){
                    this.$refs.registerFrom.validateField('checkPassword')
                }
                callback()
            }
        }

        let checkPassword = (rule, value, callback) => {
            if (value !== this.register.password) {
                callback(new Error('两次输入密码不一致!'));
            } else {
                callback();
            }
        }
        return {
        ...
        	rules{
        	...
        	 password:[
                    {required: true, message: '请输入密码', tigger: 'blur'},
                    { validator: password, tigger:'blur'},
                ],
                checkPassword:[
                    {required: true, message: '请重新输入密码', Ptigger: 'blur'},
                    { validator: checkPassword, tigger:'blur'},
                ]
             }
          ...
          }
  }

使用了$refs中的属性来验证数据正确。基本照搬 element-ui中的方法,其中validateField为验证部分表单的项目,代码中表示只验证第二次的密码。

验证码逻辑

发送验证码时,需要先要独立验证账号框 输入账号的正确性,随后进入等待期。
这里依然使用validateField 局部验证函数 由element-ui的官方文档可知,改函数有两个参数
第一个参数为字符串类型的验证值,第二个参数为 一个回调函数,函数的参数是字符串类型的错误信息(正确无信息)可以参考async-validator库 等待期的按钮风格也会变,所以须在按钮上绑定新的数据。

...
<el-button 
    :type="btnStatue" 
    @click="sendCode">{{btnContent}}</el-button>
...
...
data(){
	...
	 return {
            btnStatue: 'success',
            btnContent: '发送验证码',
            ...
     }
},
...
methods: {
	...
	sendCode(){
	   this.$refs.register.validateField('account', (msg)=>{
	       if(msg){
	           return
	       }else{
	           this.$message({
	               message: '验证码发送成功',
	               type: 'success'
	           })
	           this.btnStatue = 'info'
	           this.btnFlag = true
	           this.btnCountdown()
	       }
	   })
	},
	btnCountdown(){
	   let time = 5
	   let settime = setInterval(() => {
	       if(time === 0){
	           clearInterval(settime)
	           this.btnStatue = 'success'
	           this.btnContent = '发送验证码'
	           this.btnFlag = false
	       } else {
	           this.btnContent = `${time}秒后重试`
	           time--
	       }
	   }, 1000);
	},
 	...
}
...