系列文章目录
Vue基础篇一:编写第一个Vue程序 Vue基础篇二:Vue组件的核心概念 Vue基础篇三:Vue的计算属性与侦听器 Vue基础篇四:Vue的生命周期(秒杀案例实战) Vue基础篇五:Vue的指令 Vue基础篇六:Vue使用JSX进行动态渲染 Vue提高篇一:使用Vuex进行状态管理 Vue提高篇二:使用vue-router实现静态路由 Vue提高篇三:使用vue-router实现动态路由 Vue提高篇四:使用Element UI组件库 Vue提高篇五:使用Jest进行单元测试 Vue提高篇六: 使用Vetur+ESLint+Prettier插件提升开发效率 Vue实战篇一: 使用Vue搭建注册登录界面 Vue实战篇二: 实现邮件验证码发送
文章目录
系列文章目录一、背景二、 获取邮件验证码2.1 创建api接口2.2 调用api接口
三、验证码发送测试
一、背景
在上篇文章中,我们搭建了注册登录界面,在注册界面中,其中有这样一项功能,即用户输入邮箱后,点击发送验证码,系统后台将向用户注册的邮箱发送验证码
二、 获取邮件验证码
2.1 创建api接口
根据后台接口文档的描述,我们通过aixos组件创建对应的api接口 api.js
import request
from '@/utils/request'
export function getEmailCode(email
) {
return request({
url
: 'auth/emailCode?email=' + email
,
method
: 'post'
})
}
request.js
import axios
from 'axios'
import { Notification
} from 'element-ui'
const service
= axios
.create({
baseURL
: http
://localhost
:8000
timeout
: 10000
})
service
.interceptors
.request
.use(
config
=> {
config
.headers
['Content-Type'] = 'application/json'
return config
},
error
=> {
console
.log(error
)
Promise
.reject(error
)
}
)
service
.interceptors
.response
.use(
response
=> {
const code
= response
.status
if (code
< 200 || code
> 300) {
Notification
.error({
title
: response
.message
})
return Promise
.reject('error')
} else {
return response
.data
}
},
error
=> {
Notification
.error({
title
: '接口请求失败',
duration
: 5000
})
return Promise
.reject(error
)
}
)
export default service
2.2 调用api接口
<template>
<div class="page-register">
<article class="header">
<header>
<el-avatar icon="el-icon-user-solid" shape="circle"></el-avatar>
<span class="login">
<em class="bold">已有账号?
</em>
<a href="/login">
<el-button type="primary" size="small">登录
</el-button>
</a>
</span>
</header>
</article>
<el-steps :active="active" finish-status="success">
<el-step title="步骤 1"></el-step>
<el-step title="步骤 2"></el-step>
</el-steps>
<section>
<el-form
ref="ruleForm"
:model="ruleForm"
:rules="rules"
label-width="100px"
class="demo-ruleForm"
autocomplete="off"
>
<div v-if="active == 0">
<el-form-item prop="textarea">
<el-input
:value="ruleForm.textarea"
type="textarea"
:rows="10"
:readonly="true"
>
</el-input>
</el-form-item>
<el-form-item prop="agreed">
<el-checkbox v-model="ruleForm.agreed">同意注册协议
</el-checkbox>
</el-form-item>
</div>
<div v-if="active == 1">
<el-form-item label="用户名" prop="name">
<el-input v-model="ruleForm.name" />
</el-form-item>
<el-form-item label="邮箱" prop="email">
<el-input v-model="ruleForm.email" />
<el-button
:loading="codeLoading"
:disabled="isDisable"
size="mini"
round
@click="sendMsg"
>发送验证码
</el-button>
<span class="status">{{ statusMsg }}
</span>
</el-form-item>
<el-form-item label="验证码" prop="code">
<el-input v-model="ruleForm.code" maxlength="4" />
</el-form-item>
<el-form-item label="密码" prop="pwd">
<el-input v-model="ruleForm.pwd" type="password" />
</el-form-item>
<el-form-item label="确认密码" prop="cpwd">
<el-input v-model="ruleForm.cpwd" type="password" />
</el-form-item>
</div>
</el-form>
</section>
<div class="footer">
<el-button
v-if="active > 0"
type="info"
icon="el-icon-arrow-left"
@click="prev"
>上一步
</el-button>
<el-button
v-if="active < step - 1"
type="primary"
icon="el-icon-arrow-right"
@click="next"
>下一步
</el-button>
<el-button
v-if="active == step - 1"
type="primary"
@click="register"
>同意以下协议并注册
</el-button>
<div class="error">{{ error }}
</div>
</div>
</div>
</template>
<script>
import { getEmailCode } from '@/api'
export default {
data() {
return {
step: 2,
active: 0,
statusMsg: '',
error: '',
isDisable: false,
codeLoading: false,
ruleForm: {
textarea: '请仔细阅读以下协议',
agreed: false,
name: '',
code: '',
pwd: '',
cpwd: '',
email: ''
},
rules: {
agreed: [{
validator: (rule, value, callback) => {
if (value !== true) {
callback(new Error('请确认同意注册协议'))
} else {
callback()
}
},
trigger: 'blur'
}],
name: [{
required: true,
type: 'string',
message: '请输入用户名',
trigger: 'blur'
}],
email: [{
required: true,
type: 'email',
message: '请输入邮箱',
trigger: 'blur'
}],
pwd: [{
required: true,
message: '创建密码',
trigger: 'blur'
}, { pattern: /^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{8,20}$/, message: '密码必须同时包含数字与字母,且长度为 8-20位' }],
cpwd: [{
required: true,
message: '确认密码',
trigger: 'blur'
}, {
validator: (rule, value, callback) => {
if (value === '') {
callback(new Error('请再次输入密码'))
} else if (value !== this.ruleForm.pwd) {
callback(new Error('两次输入密码不一致'))
} else {
callback()
}
},
trigger: 'blur'
}]
}
}
},
layout: 'blank',
methods: {
sendMsg: function() {
const self = this
let namePass
let emailPass
let timerid
console.log(timerid)
if (timerid) {
return false
}
this.$refs['ruleForm'].validateField('name', (valid) => {
namePass = valid
})
self.statusMsg = ''
if (namePass) {
return false
}
this.$refs['ruleForm'].validateField('email', (valid) => {
emailPass = valid
})
if (!namePass && !emailPass) {
self.codeLoading = true
self.statusMsg = '验证码发送中...'
getEmailCode(self.ruleForm.email).then(res => {
this.$message({
showClose: true,
message: '发送成功,验证码有效期5分钟',
type: 'success'
})
let count = 60
self.ruleForm.code = ''
self.codeLoading = false
self.isDisable = true
self.statusMsg = `验证码已发送,${count--}秒后重新发送`
timerid = window.setInterval(function() {
self.statusMsg = `验证码已发送,${count--}秒后重新发送`
if (count <= 0) {
console.log('clear' + timerid)
window.clearInterval(timerid)
self.isDisable = false
self.statusMsg = ''
}
}, 1000)
}).catch(err => {
this.isDisable = false
this.statusMsg = ''
this.codeLoading = false
console.log(err.response.data.message)
})
}
},
next: function() {
if (this.active === 0) {
this.$refs['ruleForm'].validateField('agreed', (valid) => {
if (valid === '') {
this.active++
}
})
}
},
prev: function() {
this.$refs['ruleForm'].clearValidate()
if (--this.active < 0) this.active = 0
},
register: function() {
this.$refs['ruleForm'].validate((valid) => {
if (valid) {
setTimeout(
this.$router.push('/login'), 2000
)
}
})
}
}
}
</script>
<style rel="stylesheet/scss" lang="scss">
.page-register {
.header {
//border-bottom: 2px solid rgb(235, 232, 232);
min-width: 980px;
color: #666;
header {
margin: 0 auto;
padding: 10px 0;
width: 980px;
.login {
float: right;
}
.bold {
font-style: normal;
}
}
}
.register {
color: #1890ff;
}
a {
color: #1890ff;
text-decoration: none;
background-color: transparent;
outline: none;
cursor: pointer;
transition: color 0.3s;
}
> section {
margin: 0 auto 30px;
padding-top: 30px;
width: 980px;
min-height: 300px;
padding-right: 550px;
box-sizing: border-box;
.status {
font-size: 12px;
margin-left: 20px;
color: #e6a23c;
}
.error {
color: red;
}
}
.footer {
text-align: center;
}
}
</style>
三、验证码发送测试
发送验证码
邮件收到验证码