perf(verification-code): 优化验证码输入组件逻辑和样式
This commit is contained in:
@ -20,7 +20,7 @@
|
||||
</template>
|
||||
</Input.Password>
|
||||
</FormItem>
|
||||
<FormItem name="confirm_password" class="password-form-item">
|
||||
<FormItem class="password-form-item !mb-36px" name="confirm_password">
|
||||
<Input.Password
|
||||
v-model:value="formData.confirm_password"
|
||||
placeholder="密码确认"
|
||||
@ -37,7 +37,7 @@
|
||||
type="primary"
|
||||
:disabled="disabledSubmitBtn"
|
||||
:loading="submitLoading"
|
||||
class="w-full !h-48px mt-36px !rounded-8px"
|
||||
class="w-full !h-48px mt-36px !rounded-8px h-22px"
|
||||
@click="handleSubmit"
|
||||
>完成更改
|
||||
</Button>
|
||||
@ -54,7 +54,9 @@
|
||||
<p class="cts !text-12px !lh-20px !color-#939499" v-if="countdown > 0">
|
||||
{{ countdown }} 秒后您可以再次发送验证码
|
||||
</p>
|
||||
<Button type="text" class="pl-0" v-if="hasGetCode && countdown === 0" @click="getCaptcha">重新发送</Button>
|
||||
<Button v-if="hasGetCode && countdown === 0" class="pl-0 h-22px" type="text" @click="getCaptcha"
|
||||
>重新发送
|
||||
</Button>
|
||||
</template>
|
||||
</div>
|
||||
|
||||
@ -79,6 +81,11 @@ import icon2 from '@/assets/img/login/icon-open.png';
|
||||
|
||||
const emit = defineEmits(['success', 'cancel']);
|
||||
|
||||
const INITIAL_FORM_DATA = {
|
||||
captcha: '',
|
||||
password: '',
|
||||
confirm_password: '',
|
||||
};
|
||||
const visible = ref(false);
|
||||
const phone = ref('');
|
||||
const isCheckPass = ref(false);
|
||||
@ -90,11 +97,7 @@ const timer = ref<number | null>(null);
|
||||
const hasGetCode = ref(false);
|
||||
const submitLoading = ref(false);
|
||||
const verificationCodeRef = ref(null);
|
||||
const formData = ref({
|
||||
captcha: '',
|
||||
password: '',
|
||||
confirm_password: '',
|
||||
});
|
||||
const formData = ref(cloneDeep(INITIAL_FORM_DATA));
|
||||
|
||||
const formRules = {
|
||||
password: [
|
||||
@ -113,7 +116,7 @@ const formRules = {
|
||||
{
|
||||
required: true,
|
||||
validator: (_rule, value) => {
|
||||
if (value !== formData.value.password) {
|
||||
if (value && value !== formData.value.password) {
|
||||
return Promise.reject('确认密码与设置的密码不同');
|
||||
}
|
||||
return Promise.resolve();
|
||||
@ -216,6 +219,8 @@ const onClose = () => {
|
||||
countdown.value = 0;
|
||||
hasGetCode.value = false;
|
||||
submitLoading.value = false;
|
||||
isCheckPass.value = false;
|
||||
formData.valu = cloneDeep(INITIAL_FORM_DATA);
|
||||
formRef.value?.resetFields();
|
||||
formRef.value?.clearValidate();
|
||||
clearTimer();
|
||||
|
||||
@ -39,14 +39,10 @@
|
||||
|
||||
.ant-form {
|
||||
.ant-form-item {
|
||||
&:not(:last-child) {
|
||||
margin-bottom: 24px !important;
|
||||
}
|
||||
margin-bottom: 24px !important;
|
||||
|
||||
.ant-input-affix-wrapper {
|
||||
border-radius: 8px !important;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,10 +7,8 @@
|
||||
ref="inputRef"
|
||||
:key="index"
|
||||
:value="item.value"
|
||||
:class="{ error: item.error, fill: item.value }"
|
||||
:class="{ error: isError, fill: item.value }"
|
||||
@input="handleInput(index, $event.target.value)"
|
||||
@focus="handleFocus(index)"
|
||||
@blur="handleBlur(index)"
|
||||
:maxlength="1"
|
||||
placeholder=""
|
||||
/>
|
||||
@ -34,11 +32,17 @@ const emits = defineEmits(['success']);
|
||||
const codeArray = ref([]);
|
||||
const activeIndex = ref(0); // 当前激活的输入框索引
|
||||
const errorMessage = ref('');
|
||||
const isError = ref(false);
|
||||
const inputRef = ref(null);
|
||||
|
||||
// 处理输入事件
|
||||
const handleInput = (index, value) => {
|
||||
if (!value || !/^\d$/.test(value)) return;
|
||||
if (!value) {
|
||||
return;
|
||||
}
|
||||
|
||||
isError.value = false;
|
||||
errorMessage.value = '';
|
||||
|
||||
codeArray.value[index].value = value;
|
||||
|
||||
@ -48,45 +52,36 @@ const handleInput = (index, value) => {
|
||||
}
|
||||
};
|
||||
|
||||
const handleFocus = (index) => {
|
||||
activeIndex.value = index;
|
||||
};
|
||||
|
||||
const handleBlur = (index) => {
|
||||
const _value = codeArray.value[index].value;
|
||||
if (!_value || !/^\d$/.test(_value)) {
|
||||
codeArray.value[index].error = true;
|
||||
} else {
|
||||
if (errorMessage.value) {
|
||||
codeArray.value.forEach((item) => {
|
||||
item.error = false;
|
||||
});
|
||||
}
|
||||
errorMessage.value = '';
|
||||
codeArray.value[index].error = false;
|
||||
}
|
||||
};
|
||||
|
||||
// 验证验证码逻辑
|
||||
const validateCode = async () => {
|
||||
const captcha = codeArray.value.map((item) => item.value).join('');
|
||||
const { code } = await postCheckUpdatePasswordCaptcha({ captcha });
|
||||
if (code === 200) {
|
||||
emits('success', captcha);
|
||||
} else {
|
||||
activeIndex.value = 0;
|
||||
inputRef.value?.[activeIndex.value]?.focus?.();
|
||||
errorMessage.value = '验证码错误,请检查后重试';
|
||||
codeArray.value.forEach((item) => {
|
||||
item.error = true;
|
||||
item.value = '';
|
||||
});
|
||||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
isError.value = codeArray.value.some((_value) => !_value);
|
||||
isError.value ? reject() : resolve();
|
||||
});
|
||||
};
|
||||
|
||||
const onSubmit = () => {
|
||||
validateCode().then(async () => {
|
||||
const captcha = codeArray.value.map((item) => item.value).join('');
|
||||
const { code } = await postCheckUpdatePasswordCaptcha({ captcha });
|
||||
if (code === 200) {
|
||||
emits('success', captcha);
|
||||
} else {
|
||||
activeIndex.value = 0;
|
||||
inputRef.value?.[activeIndex.value]?.focus?.();
|
||||
errorMessage.value = '验证码错误,请检查后重试';
|
||||
isError.value = true;
|
||||
codeArray.value.forEach((item) => {
|
||||
item.value = '';
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const init = () => {
|
||||
activeIndex.value = 0;
|
||||
errorMessage.value = '';
|
||||
isError.value = false;
|
||||
inputRef.value = null;
|
||||
codeArray.value = new Array(6).fill().map(() => ({ value: '', error: false }));
|
||||
|
||||
@ -100,7 +95,7 @@ watch(
|
||||
() => codeArray.value,
|
||||
(newVal) => {
|
||||
if (newVal.every((item) => item.value)) {
|
||||
validateCode();
|
||||
onSubmit();
|
||||
}
|
||||
},
|
||||
{ deep: true },
|
||||
@ -129,17 +124,20 @@ defineExpose({ init });
|
||||
|
||||
caret-color: #6d4cfe;
|
||||
|
||||
&.error {
|
||||
border-color: #f64b31 !important;
|
||||
}
|
||||
&:hover {
|
||||
border-color: #6d4cfe !important;
|
||||
}
|
||||
|
||||
&:focus-within {
|
||||
border-color: #6d4cfe !important;
|
||||
}
|
||||
|
||||
&.fill {
|
||||
color: #6d4cfe;
|
||||
}
|
||||
|
||||
&.error {
|
||||
border-color: #f64b31 !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -182,14 +182,13 @@ const formRules = {
|
||||
{
|
||||
required: true,
|
||||
validator: (_rule, value) => {
|
||||
console.log('validator');
|
||||
// if (!value) {
|
||||
// return Promise.reject('请输入密码确认');
|
||||
// }
|
||||
// if (value.length < 6) {
|
||||
// return Promise.reject('密码长度不能小于6位');
|
||||
// }
|
||||
if (value !== formData.value.password) {
|
||||
if (value && value !== formData.value.password) {
|
||||
return Promise.reject('确认密码与设置的密码不同');
|
||||
}
|
||||
return Promise.resolve();
|
||||
|
||||
Reference in New Issue
Block a user