密码字段在点击填写的时候,右侧弹出校验密码强度的浮框:
<a-popover
placement="rightTop"
:trigger="['focus']"
:getPopupContainer="(trigger) => trigger.parentElement"
v-model="state.passwordLevelChecked"
>
<template slot="content">
<div :style="{ width: '240px' }">
<div :class="['user-register', passwordLevelClass]">
强度:
<span>{
{ passwordLevelName }}</span>
</div>
<a-progress
:percent="state.percent"
:showInfo="false"
:strokeColor=" passwordLevelColor "
/>
<div style="margin-top: 20px;">
<span>
密码为至少8个字符,包含字母、数字、特殊字符,区分大小写。
<br />不支持空格。
<br />请不要使用容易被猜到的密码。
</span>
</div>
</div>
</template>
<a-form-item
label="密码"
style="width:500px;margin-left: -40px"
v-bind="formItemLayout"
>
<a-input
class="w300"
@click="passwordClick"
@blur="passwordBlur"
:maxLength="30"
type="password"
v-decorator="[
'password',
{
rules: [
{ required: true, validator: this.handlePasswordLevel}
],
validateTrigger: ['change', 'blur']
}
]"
/>
</a-form-item>
</a-popover>
其中校验密码强度的一些信息,包含强度等级、对应不同强度的进度条颜色等,我们在这里定义:
const levelNames = {
0: '很低',
1: '低',
2: '中',
3: '强'
}
const levelClass = {
0: 'error',
1: 'error',
2: 'warning',
3: 'success'
}
const levelColor = {
0: '#ff0000',
1: '#ff0000',
2: '#ff7e05',
3: '#52c41a'
}
export default {
......
}
data () {
return {
state: {
time: 60,
smsSendBtn: false,
passwordLevel: 0, // 默认的密码强度等级
passwordLevelChecked: false, // 是否开启强度等级校验
percent: 10,
progressColor: '#FF0000'
},
......
}
}
html上使用的一些state中定义的样式,我们在这里引用:
computed: {
passwordLevelClass () {
return levelClass[this.state.passwordLevel]
},
passwordLevelName () {
return levelNames[this.state.passwordLevel]
},
passwordLevelColor () {
return levelColor[this.state.passwordLevel]
}
},
密码上使用@click和@blur方法来判断当前是否需要显示密码强度校验的浮窗:
// 是否显示密码强度校验
passwordClick () {
this.state.passwordLevelChecked = true
},
passwordBlur () {
this.state.passwordLevelChecked = false
},
接下来就是密码强度校验过程中,前端需要做的实时验证和提示的信息了,这个方法我们是在密码的v-decorator装饰器中,在校验规则rule中调用验证的:
handlePasswordLevel (rule, value, callback) {
let level = 0
// 密码为空时
if (value === undefined || value === '') {
this.state.percent = 10
this.state.passwordLevel = 0
return callback(new Error('请输入密码'))
}
// 包含空格时
if (!/^\S*$/.test(value)) {
return callback(new Error('密码不能包含空格'))
}
// 长度小于8个字符时
if (value.length < 8) {
this.state.percent = 10
this.state.passwordLevel = 0
return callback(new Error('至少8位密码,区分大小写。'))
}
// 判断字符串中有没有数字
if (/\d/.test(value)) {
level++
}
// 判断字符串中有没有字母
if (/[a-zA-Z]/.test(value)) {
level++
}
// 判断字符串中有没有特殊符号
if (/\W/.test(value)) {
level++
}
let percent = 10
switch (level) {
case 0:
percent = 10
break
case 1:
percent = 30
break
case 2:
percent = 60
break
case 3:
percent = 100
break
}
this.state.percent = percent
this.state.passwordLevel = level
if (level === 0 || level === 1) {
return callback(new Error('密码强度过低'))
}
return callback()
},
补充一下state中用到的颜色等样式,写在script中即可:
<style lang="less" scoped>
.user-register {
&.error {
color: #ff0000;
}
&.warning {
color: #ff7e05;
}
&.success {
color: #52c41a;
}
}
.user-layout-register {
.ant-input-group-addon:first-child {
background-color: #fff;
}
}
</style>
————————————————————————————————
同样的,确认密码字段我们也要加上判断,验证输入的确认密码是否和密码字段一样:
<a-form-item
label="确认密码"
style="width:500px;margin-left: -40px"
v-bind="formItemLayout"
>
<a-input
class="w300"
:maxLength="30"
type="password"
v-decorator="[
'confirmPassword',
{
rules: [
{ required: true, validator: this.handlePasswordCheck}
],
validateTrigger: ['change', 'blur']
}
]"
/>
</a-form-item>
其中,校验的方法这样写就可以了:
// 确认密码校验
handlePasswordCheck (rule, value, callback) {
const password = this.form.getFieldValue('password')
if (value === undefined || value === '') {
callback(new Error('请输入确认密码'))
}
if (value && password && value.trim() !== password.trim()) {
callback(new Error('两次输入密码不相同,请重新输入。'))
}
callback()
},