持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第1天,点击查看活动详情
Vue2 中封装密码输入框组件
该组件主要实现了以下三块内容:
- 密码值的显示与隐藏
- 密码强度的检测
- 提示文字的显示与隐藏
最终的实现效果:
1.密码组件的基本介绍
1.1 参数与事件
参数见下表:
参数 | 说明 | 类型 | 是否必填 | 默认值 |
---|---|---|---|---|
value | 密码值 | String | 是 | —— |
PWStrengthTest | 是否开启密码检测 | Boolean | 否 | false |
PWLevel | 密码强度 | Number | 否 | 0 |
事件见下表:
事件 | 说明 | 形参 |
---|---|---|
changeValue | 密码值变化时触发 | 新的密码值 |
changePWLevel | 密码强度变化时触发 | 新的密码强度 |
1.2 使用该组件的示例
<template>
<form class="form">
<PasswordComp
:value="passwordVal"
@changeValue="passwordVal = $event"
:PWStrengthTest="true"
:PWLevel="PWLevel"
@changePWLevel="PWLevel = $event"
></PasswordComp>
</form>
</template>
<script>
import PasswordComp from "@/components/PasswordComp.vue";
export default {
components: {
PasswordComp,
},
data() {
return {
passwordVal: "",
PWLevel: 0,
};
},
};
</script>
2. 功能的实现原理
2.1 密码的显示与隐藏
控制密码的显示与隐藏的主要思路:
- 点击小眼睛图标触发input 元素的 type 属性值的更改
- 密码显示时
type=text
- 密码隐藏时
type=password
- 密码显示时
在 vue 中使用 computed 计算属性来监听 data 中的 isShow 值,得出 input 元素的 type 属性值以及 img 元素的 src 属性值。 该部分的主要代码如下:
<template>
<div class="password-container">
<div class="password">
<input
ref="password"
name="password"
maxlength="16"
:type="inputType"
/>
<img :src="imgSrc" alt="eye" @click="changeType" />
</div>
</div>
</template>
<script>
export default {
props: {
value: {
type: String,
required: true,
}
},
data() {
return {
isShow: false, //密码的显示与隐藏 true表示显示 false表示隐藏
};
},
computed: {
inputType() {
return this.isShow ? "text" : "password";
},
imgSrc() {
return this.isShow
? "https://s4.ax1x.com/2022/01/07/79E7dg.png"
: "https://s4.ax1x.com/2022/01/07/79EOWn.png";
},
},
methods: {
//改变显示模式
changeType() {
this.isShow = !this.isShow;
},
},
};
</script>
2.2 密码强度的检测
检测密码强度主要思路是:
- 每当父组件通过 props 属性传入 value 值时,子组件先通过 watch 监听该值并使用正则表达式来计算强度,再通过 computed 计算属性与 class 类名来进行相应的样式控制。
该部分的主要代码如下:
<template>
<div class="password-container">
<div class="password">
<input
ref="password"
name="password"
maxlength="16"
:value="value"
@input="changeValue"
/>
</div>
<div class="PWStrengthTest" v-if="PWStrengthTest">
<span>密码强度</span>
<span v-if="PWLevel">:</span>
<span
class="PWString"
:class="{
easy: PWLevel === 1,
medium: PWLevel === 2,
difficulty: PWLevel === 3 || PWLevel === 4,
}"
>{{ PWLevelText }}
</span>
</div>
</div>
</template>
<script>
export default {
props: {
value: {
type: String,
required: true,
},
PWStrengthTest: {
type: Boolean,
default: false, //true表示开启密码检测 false表示关闭
},
PWLevel: {
type: Number,
default: 0, //0表示未输入 1表示弱 2表示中单 3表示强 4表示很强
},
},
computed: {
PWLevelText() {
if (this.PWLevel === 0) {
return "";
} else if (this.PWLevel === 1) {
return "弱";
} else if (this.PWLevel === 2) {
return "中等";
} else if (this.PWLevel === 3) {
return "强";
} else if (this.PWLevel === 4) {
return "很强";
}
},
},
methods: {
//改变密码的值
changeValue() {
this.$emit("changeValue", this.$refs.password.value);
},
},
watch: {
//检测密码强度
value: function (newVal) {
if (!this.PWStrengthTest) return;
let curPWLevel = 0;
if (newVal.length >= 6) {
//密码长度大于6时开始监测密码等级
if (/\d/.test(newVal)) curPWLevel++; //数字
if (/[a-z]/.test(newVal)) curPWLevel++; //小写字母
if (/[A-Z]/.test(newVal)) curPWLevel++; //大写字母
if (/\W/.test(newVal)) curPWLevel++; //特殊字符
}
if (curPWLevel !== this.PWLevel) {
this.$emit("changePWLevel", curPWLevel);
}
},
},
};
</script>
2.3 提示文字的显示与隐藏
控制提示文字的显示与隐藏的主要思路是:
- 通过 data 属性中的 msgShow 来控制该元素的 visibility 属性值
- 密码框触发 focus 事件时,将
msgShow = true
- 密码框触发 blur 事件时,将
msgShow = false
- 密码框触发 focus 事件时,将
该部分的主要代码如下:
<template>
<div class="password-container">
<p class="msg" :class="{ active: msgShow }">
请输入6-16位的密码(至少包含两种字符类型)
</p>
<div class="password">
<input
ref="password"
name="password"
maxlength="16"
@focus="msgShow = true"
@blur="msgShow = false"
/>
</div>
</div>
</template>
<script>
export default {
data() {
return {
msgShow: false, //提示文字的显示与隐藏
};
},
};
</script>
3. 组件的完整代码
<template>
<div class="password-container">
<p class="msg" :class="{ active: msgShow }">
请输入6-16位的密码(至少包含两种字符类型)
</p>
<div class="password">
<input
ref="password"
name="password"
maxlength="16"
:type="inputType"
:value="value"
@input="changeValue"
@focus="msgShow = true"
@blur="msgShow = false"
/>
<img :src="imgSrc" alt="eye" @click="changeType" />
</div>
<div class="PWStrengthTest" v-if="PWStrengthTest">
<span>密码强度</span>
<span v-if="PWLevel">:</span>
<span
class="PWString"
:class="{
easy: PWLevel === 1,
medium: PWLevel === 2,
difficulty: PWLevel === 3 || PWLevel === 4,
}"
>{{ PWLevelText }}
</span>
</div>
</div>
</template>
<script>
export default {
props: {
value: {
type: String,
required: true,
},
PWStrengthTest: {
type: Boolean,
default: false, //true表示开启密码检测 false表示关闭
},
PWLevel: {
type: Number,
default: 0, //0表示未输入 1表示弱 2表示中单 3表示强 4表示很强
},
},
data() {
return {
isShow: false, //密码的显示与隐藏 true表示显示 false表示隐藏
msgShow: false, //提示文字的显示与隐藏
};
},
computed: {
inputType() {
return this.isShow ? "text" : "password";
},
imgSrc() {
return this.isShow
? "https://s4.ax1x.com/2022/01/07/79E7dg.png"
: "https://s4.ax1x.com/2022/01/07/79EOWn.png";
},
PWLevelText() {
if (this.PWLevel === 0) {
return "";
} else if (this.PWLevel === 1) {
return "弱";
} else if (this.PWLevel === 2) {
return "中等";
} else if (this.PWLevel === 3) {
return "强";
} else if (this.PWLevel === 4) {
return "很强";
}
},
},
methods: {
//改变显示模式
changeType() {
this.isShow = !this.isShow;
},
//改变密码的值
changeValue() {
this.$emit("changeValue", this.$refs.password.value);
},
},
watch: {
//检测密码强度
value: function (newVal) {
if (!this.PWStrengthTest) return;
let curPWLevel = 0;
if (newVal.length >= 6) {
//密码长度大于6时开始监测密码等级
if (/\d/.test(newVal)) curPWLevel++; //数字
if (/[a-z]/.test(newVal)) curPWLevel++; //小写字母
if (/[A-Z]/.test(newVal)) curPWLevel++; //大写字母
if (/\W/.test(newVal)) curPWLevel++; //特殊字符
}
if (curPWLevel !== this.PWLevel) {
this.$emit("changePWLevel", curPWLevel);
}
},
},
};
</script>
<style lang="scss" scoped>
.password-container {
width: 300px;
display: flex;
flex-direction: column;
.msg {
align-self: flex-end;
font-size: 14px;
margin: 0;
color: #ccc;
visibility: hidden;
&.active {
visibility: visible;
}
}
.password {
position: relative;
input {
margin-top: auto;
width: 100%;
height: 28px;
box-sizing: border-box;
outline: none;
border: 1px solid #4d4ddb;
border-radius: 2px;
padding: 0 6px;
&:focus {
border: 1px solid #000;
}
}
img {
position: absolute;
width: 14px;
height: 14px;
top: 50%;
right: 5px;
transform: translateY(-50%);
cursor: pointer;
}
}
.PWStrengthTest {
width: 100%;
margin-top: 4px;
font-size: 14px;
display: flex;
span {
font-size: 14px;
}
.PWString {
&.easy {
color: rgb(251, 7, 7);
}
&.medium {
color: rgb(255, 185, 0);
}
&.difficulty {
color: rgb(0, 255, 133);
}
}
}
}
</style>
结语
这是我目前所了解的知识面中最好的解答,当然也有可能存在一定的误区。
所以如果对本文存在疑惑,可以在评论区留言,我会及时回复的,欢迎大家指出文中的错误观点。
最后码字不易,觉得有帮助的朋友点赞、收藏、关注走一波。