From a1d7e81859f554f3a53680cc35f0f49bf1f77098 Mon Sep 17 00:00:00 2001
From: wwf <1971391498@qq.com>
Date: 星期四, 14 五月 2026 14:37:02 +0800
Subject: [PATCH] 导入项目
---
src/components/InputPassword/src/InputPassword.vue | 152 ++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 152 insertions(+), 0 deletions(-)
diff --git a/src/components/InputPassword/src/InputPassword.vue b/src/components/InputPassword/src/InputPassword.vue
new file mode 100644
index 0000000..b8c93e7
--- /dev/null
+++ b/src/components/InputPassword/src/InputPassword.vue
@@ -0,0 +1,152 @@
+<script lang="ts" setup>
+import { propTypes } from '@/utils/propTypes'
+import { useConfigGlobal } from '@/hooks/web/useConfigGlobal'
+import type { ZxcvbnResult } from '@zxcvbn-ts/core'
+import { zxcvbn } from '@zxcvbn-ts/core'
+import { useDesign } from '@/hooks/web/useDesign'
+
+defineOptions({ name: 'InputPassword' })
+
+const { getPrefixCls } = useDesign()
+
+const prefixCls = getPrefixCls('input-password')
+
+const props = defineProps({
+ // 鏄惁鏄剧ず瀵嗙爜寮哄害
+ strength: propTypes.bool.def(false),
+ modelValue: propTypes.string.def('')
+})
+
+watch(
+ () => props.modelValue,
+ (val: string) => {
+ if (val === unref(valueRef)) return
+ valueRef.value = val
+ }
+)
+
+const { configGlobal } = useConfigGlobal()
+
+const emit = defineEmits(['update:modelValue'])
+
+// 璁剧疆input鐨則ype灞炴��
+const textType = ref<'password' | 'text'>('password')
+
+const changeTextType = () => {
+ textType.value = unref(textType) === 'text' ? 'password' : 'text'
+}
+
+// 杈撳叆妗嗙殑鍊�
+const valueRef = ref(props.modelValue)
+
+// 鐩戝惉
+watch(
+ () => valueRef.value,
+ (val: string) => {
+ emit('update:modelValue', val)
+ }
+)
+
+// 鑾峰彇瀵嗙爜寮哄害
+const getPasswordStrength = computed(() => {
+ const value = unref(valueRef)
+ const zxcvbnRef = zxcvbn(unref(valueRef)) as ZxcvbnResult
+ return value ? zxcvbnRef.score : -1
+})
+
+const getIconName = computed(() => (unref(textType) === 'password' ? 'ep:hide' : 'ep:view'))
+</script>
+
+<template>
+ <div :class="[prefixCls, `${prefixCls}--${configGlobal?.size}`]">
+ <ElInput v-model="valueRef" :type="textType" v-bind="$attrs">
+ <template #suffix>
+ <Icon :icon="getIconName" class="el-input__icon cursor-pointer" @click="changeTextType" />
+ </template>
+ </ElInput>
+ <div
+ v-if="strength"
+ :class="`${prefixCls}__bar`"
+ class="relative mb-6px ml-auto mr-auto mt-10px h-6px"
+ >
+ <div :class="`${prefixCls}__bar--fill`" :data-score="getPasswordStrength"></div>
+ </div>
+ </div>
+</template>
+
+<style lang="scss" scoped>
+$prefix-cls: #{$namespace}-input-password;
+
+.#{$prefix-cls} {
+ :deep(.#{$elNamespace}-input__clear) {
+ margin-left: 5px;
+ }
+
+ &__bar {
+ background-color: var(--el-text-color-disabled);
+ border-radius: var(--el-border-radius-base);
+
+ &::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%;
+ }
+
+ &--fill {
+ 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);
+ }
+ }
+ }
+
+ &--mini > &__bar {
+ border-radius: var(--el-border-radius-small);
+ }
+}
+</style>
--
Gitblit v1.8.0