Vue+element登录页面实现拼图验证
- 需求分析
- 一、导入
- 二、验证的意义
- 三、常规验证手段
- 详细设计
- 一、使用组件
- 二、轮子已找好,开始拼凑
- 效果展示
- 结尾
需求分析
一、导入
项目开发过程中,遇到过一个简单的需求,即登录界面的 验证操作。
登录流程如下:
二、验证的意义
为什么会需要验证呢?其中一个重要的作用就是防止用户利用机器人自动注册、登录、灌水。
验证码的出现是为了提高攻击者的付出成本。尽管现在的爬虫对于简单的验证已经能够绕过,但是依旧需要抓取登录界面的信息来模拟,需要一定的攻击成本。而此时后端的登录验证框架就显得尤为重要了。当然这是后话。
三、常规验证手段
目前常规的前端界面验证手段有如下几种:
- 字符验证:根据图片中的字母或数字,填写验证。
- 运算验证:根据运算表达式,填写答案验证
- 拼图验证:根据图片上截取的缺口,滑动图片到缺口位置,判断是否匹配,完成验证。
- 选字验证:以B站登录界面弹出的选字验证为例。
- 选图验证:如12306上面的验证,根据提示的类型,如选出下面包含自行车的图片等。
具体样式可查看 前端验证码
详细设计
在常规验证手段中,字符验证和运算验证干扰程度低,且拉低审美。选取方案中被首先排除。
然后选字验证和选图验证过于复杂,对于一般的小型网站设计,完全没有必要!
那么最后的幸运儿就是: 拼图验证 。
一、使用组件
Vue框架的一大优点就是组件化设计思想,对于重复的元素可以提取成一个组件,然后按需引入或者全局注册。
那么为贯彻迅儿的”拿来主义“,咱们也去搬一搬,找一找大佬已经设计好的拼图验证子组件吧。
这儿是传送带: Vue拼图验证组件
使用方法
npm i vue-puzzle-verification 安装组件
-
在main.js中引用
:
import PuzzleVerification from 'vue-puzzle-verification'
// 使用封装的登录验证vue组件
Vue.use(PuzzleVerification);
二、轮子已找好,开始拼凑
首先,前端需要绘制出登录界面:
Login.vue
<template>
<div id="login">
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
<el-form :model="loginForm" :rules="rules" class="login-container" size="medium" @keyup.enter.native="handleClick">
<h3 class="login_title">用户登录</h3>
<el-form-item prop="username" >
<el-input type="text" v-model="loginForm.username" autofocus ref="username"
auto-complete="off" placeholder="用户名/邮箱" prefix-icon="el-icon-user-solid" spellcheck="false">
</el-input>
</el-form-item>
<el-form-item prop="password">
<el-input type="password" v-model="loginForm.password" autofocus ref="password"
auto-complete="off" placeholder="密码" prefix-icon="el-icon-key" v-on:input="change">
</el-input>
</el-form-item>
<el-form-item style="width: 100%;">
<el-checkbox class="login_remember" v-model="checked" >
<span style="color: #409EFF">记住我</span>
<label style="color: #949493">不是自己电脑请勿勾选</label>
</el-checkbox>
<router-link to="resetPassword" style="float: right; text-decoration: none; color: #50b6ff">找回密码?</router-link>
</el-form-item>
<el-form-item style="width: 100%">
<el-button type="primary" class="button_login" @click="handleClick()">登录</el-button>
<router-link to="register">
<el-button type="primary" class="button_register">注册</el-button>
</router-link>
</el-form-item>
</el-form>
</el-col>
<el-popover
placement="bottom"
trigger="click" style="opacity: 0.7">
<template #reference>
<!--滑动图片弹窗验证-->
<PuzzleVerification v-model="isVerificationShow" :puzzleImgList="puzzleImgList" blockType="puzzle"
:onSuccess="handleSuccess" :onError="handleError"/>
</template>
</el-popover>
<p class="login-copyright">© 2020 lkq 版权所有</p>
</div>
</template>
<script>
import PuzzleVerification from 'vue-puzzle-verification'
export default {
components: {PuzzleVerification},
name: 'Login',
data() {
return {
isVerificationShow: false,
rules: {
username: [{required: true, message: '用户名或邮箱不能为空', trigger: 'change'}],
password: [{required: true, message: '密码不能为空', trigger: 'change'}]
},
checked: true,
loginForm: {
username: '',
password: ''
},
puzzleImgList: [
require("../../assets/images/verify/1.jpg"),
require("../../assets/images/verify/2.jpg"),
require("../../assets/images/verify/3.jpg"),
require("../../assets/images/verify/4.jpg"),
require("../../assets/images/verify/5.jpg"),
require("../../assets/images/verify/6.jpg"),
require("../../assets/images/verify/7.jpg"),
require("../../assets/images/verify/8.jpg"),
require("../../assets/images/verify/9.jpg"),
require("../../assets/images/verify/10.jpg"),
],
isInput: false,
}
},
methods: {
handleSuccess() {
// 验证通过后关闭图片验证
this.isVerificationShow = false;
// 将数据传送到后端验证
console.log("验证成功")
// 将数据传送到后端验证
this.login()
},
handleError() {
// 滑动验证失败
console.log("验证失败")
},
handleClick() {
if (this.loginForm.username === '' || this.loginForm.password === '') {
// 点击登录时,如果用户名或者密码未输入,那么提醒用户输入
if (this.loginForm.username === '') {
this.$message({
message: '警告, 用户名或邮箱未输入哦',
type: 'warning'
});
this.$refs.username.focus();
}else {
this.$message({
message: '警告, 密码未输入呀',
type: 'warning'
});
this.$refs.password.focus();
}
}else {
this.isVerificationShow = true;
}
},
change() {
// 如果监听到输入框发生变化,那么采用用户输入的密码
this.isInput = true;
},
login() {
//..,将数据传送给后端
}
}
}
</script>
<style scoped >
@import "../../assets/css/login.css";
</style>
简单解释一下:
-
:model="loginForm"
: 表单的数据对象。 -
:rules="rules
: 表单验证规则。 -
@keyup.enter.natice="handleClick"
: enter键函数,用户输入数据后可以直接enter键,不一定要点击按钮。 -
记住我
:利用cookie来存储登录信息,不是重点。 -
找回密码
:利用邮箱找回密码,不是重点,下一趴再介绍吧。 -
el-popover
: element中的弹出框,作为容器。 -
trigger=click
: 触发方式,点击触发。 -
#reference
: 触发 Popover 显示的 HTML 元素。 -
:puzzleImgList="puzzleImgList"
: 传入的拼图背景图片。 -
blockType
:滑块的形状。
对应的Css样式
#login {
background-image: url('../login_img.jpg');
background-repeat: no-repeat;
background-size: cover;
height: 100%;
width: 100%;
position: fixed;
}
.login-container {
border-radius: 15px;
background-clip: padding-box;
margin: 10% 40% 0 40%;
width: 20%;
padding: 25px 30px;
background: #fff;
border: 1px solid #eaeaea;
box-shadow: 0 0 25px #cac6c6;
opacity: 0.7;
}
.login_title {
margin: 0px auto 40px auto;
text-align: center;
color: #505458;
}
.login_remember {
margin: 0px;
text-align: left;
float: left;
}
.button_login {
width: 40%;
background: #409EFF;
border: none;
float: left
}
.button_register {
width: 40%;
background: #505458;
border: none;
float: right;
}
.login-copyright {
color: #eee;
padding-bottom: 20px;
text-align: center;
position: relative;
z-index: 1;
}
@media screen and (min-height: 550px) {
.login-copyright {
position: absolute;
bottom: 0;
right: 0;
left: 0;
}
}
效果展示
登录界面:
点击登录后:
控制台查看回调函数:
这里是滑动成功后截屏,控制台还未输出。
结尾
又是一个安静的晚上,一个人窝在摇椅里乘凉!