1、小眼睛可以显示/隐藏明文密码(无法用input type=password,用css样式实现切换明文)
2、输入长度统计(不是自带的,用div写的,然后定位到框内的)
3、每输入一个字符分别验证每一项规则,符合就变绿色,删掉符合字符就变红色
4、根据符合规则的长度,判断密码强弱
HTML:
<template>
<div class="InitializesSystemKey">
<div class="password-box">
<div class="password-box-title">
<span>初始化系统秘钥</span>
<Button style="margin: 15px 0;" @click="clickReturn">返回</Button>
</div>
<div class="password-box-set">
<div class="password-box-set-title">
设置秘钥
</div>
<div class="password-box-set-con">
<div class="password-box-set-con-text">
<span>
设置秘钥
<eye-outlined v-if="!isEye" @click="isEye = true" style="color: #0E56C0;"/>
<eye-invisible-outlined v-if="isEye" @click="isEye = false" style="color: #0E56C0;" />
</span>
<span style="font-size: 14px;color: #88909B;">{{ text }}</span>
</div>
<div class="password-box-set-con-input">
<a-textarea v-model:value="inputVal" type="password" :rows="4" placeholder="请输入" @change="changeInput" :maxlength="256" :minlength="8" :style="isEye ? { '-webkit-text-security': 'disc' } : {}" />
<div class="counter">{{ charCount }}/256</div>
</div>
<!-- 验证规则显示 -->
<div class="password-box-set-con-rule">
<div>
<check-outlined v-if="isLargeLetter" style="color: #3AA679;"/>
<close-outlined v-if="!isLargeLetter" style="color: #E53A2F;"/>
<span :class="isLargeLetter ? 'colorGreen' : 'colorRed'">包含大写字母</span>
</div>
<div>
<check-outlined v-if="isSmallLetter" style="color: #3AA679;"/>
<close-outlined v-if="!isSmallLetter" style="color: #E53A2F;"/>
<span :class="isSmallLetter ? 'colorGreen' : 'colorRed'">包含小写字母</span>
</div>
<div>
<check-outlined v-if="isNumber" style="color: #3AA679;"/>
<close-outlined v-if="!isNumber" style="color: #E53A2F;"/>
<span :class="isNumber ? 'colorGreen' : 'colorRed'">包含数字</span>
</div>
<div>
<check-outlined v-if="isSpecSymbol" style="color: #3AA679;"/>
<close-outlined v-if="!isSpecSymbol" style="color: #E53A2F;"/>
<span :class="isSpecSymbol ? 'colorGreen' : 'colorRed'">包含特殊符号</span>
</div>
<div>
<check-outlined v-if="isLength" style="color: #3AA679;"/>
<close-outlined v-if="!isLength" style="color: #E53A2F;"/>
<span :class="isLength ? 'colorGreen' : 'colorRed'">秘钥长度16-256位</span>
</div>
</div>
<div class="password-box-set-con-progress">
<div class="password-box-set-con-progress-left">
<div style="margin-left: 15px;" class="password-box-set-con-progress-left-col">
<p :style="numLength == 1 ? { 'background': '#F8584D' } : {}"></p>
<caret-up-outlined />
<span :style="numLength == 1 ? { 'color': '#F8584D' } : {}">弱</span>
</div>
<div class="password-box-set-con-progress-left-col">
<p :style="numLength == 2 ? { 'background': '#FAB247' } : {}"></p>
<caret-up-outlined />
<span :style="numLength == 2 ? { 'color': '#FAB247' } : {}">中</span>
</div>
<div class="password-box-set-con-progress-left-col">
<p :style="numLength >= 3 ? { 'background': '#3AA679' } : {}"></p>
<caret-up-outlined />
<span :style="numLength >= 3 ? { 'color': '#3AA679' } : {}">强</span>
</div>
</div>
<div class="password-box-set-con-progress-btn">
<Button @click="">提交秘钥</Button>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
CSS:
.InitializesSystemKey {
position: fixed;
bottom: 0;
top: 50px;
right: 0;
left: 0;
z-index: 999;
width: 100vw;
height: calc(100vh-50px);
background: #f8f8f9;
.password-box{
position: absolute;
top: 10%;
left: 50%;
// transform: translate(-50%, -50%);
margin-left: -450px;
width: 900px;
height: 500px;
&-title{
display: flex;
flex-direction: row;
justify-content: space-between;
span{
color: #D91313;
font-size: 40px;
}
}
&-set{
background: #fff;
border-radius: 10px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
&-title{
padding: 10px;
border-bottom: 1px solid #E5E6EB;
font-size: 20px;
font-weight: 600;
}
&-con{
display: flex;
flex-direction: column;
&-text{
display: flex;
flex-direction: row;
justify-content: space-between;
padding: 15px 10px;
span{
font-size: 16px;
color: #1D2128;
}
}
&-input{
padding: 0 10px;
position: relative;
border-radius: 10px;
// 让计数在边框内
.counter {
position: absolute;
bottom: 10px;
right: 20px;
padding: 0 5px;
}
}
&-rule{
display: flex;
flex-direction: row;
justify-content: flex-start;
padding: 10px;
gap: 15px;
span{
margin-left: 2px;
}
.colorGreen{
color: #3AA679;
}
.colorRed{
color: #E53A2F;
}
}
&-progress{
border-top: 1px solid #E5E6EB;
padding: 15px 0 10px;
display: flex;
flex-direction: row;
justify-content: space-between;
&-left{
padding: 15px 0 10px;
display: flex;
flex-direction: row;
gap: 5px;
&-col{
display: flex;
flex-direction: column;
align-items: center;
p{
width: 100px;
height: 8px;
background: #E5E6EB;
margin: 0;
}
}
}
&-btn{
margin: 10px 25px 0 0;
}
}
}
}
}
}
JS逻辑:
import { onMounted, ref,computed} from 'vue';
import Button from '@/views/salary/components/button.vue';
const text = ref("请输入16~256位秘钥,需包含大小写、数字、特殊字符(仅支持以下字符:()`!@#$%^&*_-+=|{}[]:;'<>,.?")
const isEye =ref(true);
const inputVal = ref('');
const numLength = computed(() => {
return [isLargeLetter.value, isSmallLetter.value, isNumber.value, isSpecSymbol.value,isLength.value].filter(Boolean).length;
})
const charCount = computed(() => {
return inputVal.value.length;
})
const isLargeLetter = ref(false);
const isSmallLetter = ref(false);
const isNumber = ref(false);
const isSpecSymbol = ref(false);
const isLength =ref(false);
// input改变
const changeInput = (event)=>{
const specialChars = "()`!@#$%^&*_-+=|{}[]:;'<>,.?";
const escapedSpecialChars = specialChars.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
let key = event.target.value;
if(!key){
isLength.value = false;
isLargeLetter.value = false;
isSmallLetter.value = false;
isNumber.value = false;
isSpecSymbol.value = false;
}
// 长度
if (key.length > 16 && key.length < 256) {
isLength.value = true;
}else{
isLength.value = false;
}
// 数字
if (/\d/.test(key)) {
isNumber.value = true;
}else{
isNumber.value = false;
}
// 小写
if (/[a-z]/.test(key)) {
isSmallLetter.value = true;
}else{
isSmallLetter.value = false;
}
// 大写
if (/[A-Z]/.test(key)) {
isLargeLetter.value = true;
}else{
isLargeLetter.value = false;
}
// 特殊字符
if (new RegExp(`[${escapedSpecialChars}]`).test(key)) {
isSpecSymbol.value = true;
}else{
isSpecSymbol.value = false;
}
}
const emits = defineEmits(['clickReturn'])
const clickReturn = ()=>{
emits('close');
}
onMounted(() => {});