特性: 新增输入强度校验组件
This commit is contained in:
parent
10ac766489
commit
ebc737b8bb
|
|
@ -0,0 +1,76 @@
|
|||
.inputStrength {
|
||||
width: 100%;
|
||||
:deep(.#{'el'}-input__clear) {
|
||||
margin-left: 5px;
|
||||
}
|
||||
&-input {
|
||||
&_icon {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
&-line {
|
||||
background-color: var(--el-text-color-disabled);
|
||||
border-radius: var(--el-border-radius-base);
|
||||
position: relative;
|
||||
margin-bottom: 6px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
margin-top: 10px;
|
||||
height: 6px;
|
||||
&::before,
|
||||
&::after {
|
||||
position: absolute;
|
||||
z-index: 10;
|
||||
display: block;
|
||||
width: 20%;
|
||||
height: inherit;
|
||||
background-color: transparent;
|
||||
border-color: var(--el-color-white);
|
||||
border-style: solid;
|
||||
border-width: 0 5px;
|
||||
content: '';
|
||||
}
|
||||
|
||||
&::before {
|
||||
left: 20%;
|
||||
}
|
||||
|
||||
&::after {
|
||||
right: 20%;
|
||||
}
|
||||
|
||||
&_visual {
|
||||
position: absolute;
|
||||
width: 0;
|
||||
height: inherit;
|
||||
background-color: transparent;
|
||||
border-radius: inherit;
|
||||
transition: width 0.5s ease-in-out, background 0.25s;
|
||||
|
||||
&[data-score='0'] {
|
||||
width: 20%;
|
||||
background-color: var(--el-color-danger);
|
||||
}
|
||||
|
||||
&[data-score='1'] {
|
||||
width: 40%;
|
||||
background-color: var(--el-color-danger);
|
||||
}
|
||||
|
||||
&[data-score='2'] {
|
||||
width: 60%;
|
||||
background-color: var(--el-color-warning);
|
||||
}
|
||||
|
||||
&[data-score='3'] {
|
||||
width: 80%;
|
||||
background-color: var(--el-color-success);
|
||||
}
|
||||
|
||||
&[data-score='4'] {
|
||||
width: 100%;
|
||||
background-color: var(--el-color-success);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
<template>
|
||||
<div class="inputStrength">
|
||||
<el-input v-model="inputValue" placeholder="请输入密码" :type="textType" v-bind="$attrs" class="inputStrength-input">
|
||||
<template #suffix>
|
||||
<div class="inputStrength-input_icon" @click="changeTextType">
|
||||
<svg-icon :icon-class="passwordType ? 'eye' : 'eye-open'" />
|
||||
</div>
|
||||
</template>
|
||||
</el-input>
|
||||
<div v-if="strength" class="inputStrength-line">
|
||||
<div class="inputStrength-line_visual" :data-score="getPasswordStrength"></div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { watch, unref, ref, computed, PropType } from 'vue'
|
||||
import type { ZxcvbnResult } from '@zxcvbn-ts/core'
|
||||
import { zxcvbn } from '@zxcvbn-ts/core'
|
||||
|
||||
const props = defineProps({
|
||||
// 是否显示强度
|
||||
strength: {
|
||||
type: Boolean as PropType<boolean>,
|
||||
default: false,
|
||||
},
|
||||
modelValue: {
|
||||
type: String as PropType<string>,
|
||||
default: '',
|
||||
},
|
||||
})
|
||||
const emits = defineEmits(['update:modelValue'])
|
||||
|
||||
// 输入框的值
|
||||
const inputValue = ref(props.modelValue)
|
||||
|
||||
//输入框类型,默认密码态
|
||||
const textType = ref<'password' | 'text'>('password')
|
||||
|
||||
//切换输入框类型
|
||||
const changeTextType = () => {
|
||||
textType.value = unref(textType) === 'text' ? 'password' : 'text'
|
||||
}
|
||||
//切换icon
|
||||
const passwordType = computed(() => unref(textType) === 'password')
|
||||
|
||||
// 计算密码强度
|
||||
const getPasswordStrength = computed(() => {
|
||||
const value = unref(inputValue)
|
||||
const zxcvbnRef = zxcvbn(inputValue.value) as ZxcvbnResult
|
||||
return value ? zxcvbnRef.score : -1
|
||||
})
|
||||
|
||||
watch(
|
||||
() => props.modelValue,
|
||||
(val: string) => {
|
||||
if (val === unref(inputValue)) return
|
||||
inputValue.value = val
|
||||
},
|
||||
)
|
||||
|
||||
watch(
|
||||
() => inputValue.value,
|
||||
(val: string) => {
|
||||
emits('update:modelValue', val)
|
||||
},
|
||||
)
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import './index.scss';
|
||||
</style>
|
||||
Loading…
Reference in New Issue