You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

54 lines
1.5 KiB

<script setup lang="ts">
const props = defineProps<{ password: string }>()
const score = computed(() => {
const p = props.password
if (!p) return 0
let s = 0
const hasLower = /[a-z]/.test(p)
const hasUpper = /[A-Z]/.test(p)
const hasDigit = /\d/.test(p)
const hasSpecial = /[^a-zA-Z\d]/.test(p)
const hasLetter = hasLower || hasUpper
if (p.length >= 8 && hasLetter && hasDigit) s = 2
if (p.length >= 10 && hasLower && hasUpper && hasDigit) s = 3
if (p.length >= 12 && hasLower && hasUpper && hasDigit && hasSpecial) s = 4
// Fallback: any input < 8 or single-type = weak
if (s === 0 && p.length > 0) s = 1
return s
})
const label = computed(() => {
const labels = ['', '弱', '中', '强', '很强']
return labels[score.value]
})
const barWidth = computed(() => `${(score.value / 4) * 100}%`)
const barColor = computed(() => {
const colors = ['', 'bg-red-500', 'bg-amber-500', 'bg-green-500', 'bg-emerald-500']
return colors[score.value]
})
</script>
<template>
<div v-if="score > 0" class="mt-1 space-y-1">
<div class="h-1 w-full rounded-full bg-(--ui-bg-accented)">
<div
data-testid="strength-bar"
:data-score="score"
:class="[barColor, 'h-1 rounded-full transition-all duration-300']"
:style="{ width: barWidth }"
/>
</div>
<p class="text-xs" :class="{
'text-red-500': score === 1,
'text-amber-500': score === 2,
'text-green-500': score === 3,
'text-emerald-500': score === 4,
}">{{ label }}</p>
</div>
</template>