准备工作
- 使用Vue-cli构建的单页面组件
- 使用vrouter进行登录和注册页面转换
- 使用Element-ui 实现布局和UI
布局
Element-ui使用栅格布局,在此直接复制布局代码。
不懂栅格的可以看看这个视频(B站UP飞凡实验室的视频)。
复制代码如下:
<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 属性代表偏移栅格的数量
注册界面容器
这里我用 <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;
}
效果如下:
ps: 残影是因为录屏软件的原因。
注册主要功能的实现
实现注册需要使用表单来完成,在此提出五个注册时必须的字段:
- 用户名,可以验证唯一性
- 邮箱或者手机号,用来发送验证码
- 验证码
- 密码
- 确认密码
当然,后端的逻辑我还不会写。但需要确保邮箱或手机号的格式正确以及两次密码要一致。
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>
数据接收
使用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-item 的 el-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);
},
...
}
...