看见比较好的代码抄袭
2022-06-23 本文已影响0人
糖醋里脊120625
hooks
import { reactive, toRefs, unref } from 'vue';
import { Toast } from 'vant';
import API_VERIFICATION from '@/apis/verification';
import { sms } from '@/constants/modules/user';
import { isMobile } from '@/utils/validate';
/**
* 短信验证码
*/
export function useSmsCode() {
const state = reactive({
// 短信验证码
mobile: '',
smsCode: '',
smsTimer: null as TimeoutHandle | null,
smsText: '获取验证码',
smsCount: sms.count,
// 图形验证码
captchaShow: false,
});
function onSmsBtnClicked() {
if (!unref(state.mobile)) {
Toast('请输入手机号信息');
return;
}
if (!isMobile(unref(state.mobile))) {
Toast('手机号格式错误');
return;
}
state.captchaShow = true;
}
function onSmsSend({ requestId, code }) {
API_VERIFICATION.verificationSmsGet({
mobile: unref(state.mobile),
key: requestId,
picCode: code,
}).then(() => {
Toast({
message: '短信已发送,请查收',
duration: 2000,
});
countdown(); // 立即执行一次,避免 setInterval 延迟
state.smsTimer = setInterval(countdown, 1000);
});
}
function countdown() {
if (state.smsCount > 0) {
state.smsCount--;
state.smsText = `已发送(${state.smsCount}s)`;
} else {
state.smsCount = sms.count;
state.smsText = `重新发送`;
clearInterval(Number(state.smsTimer));
state.smsTimer = null;
}
}
return {
...toRefs(state),
onSmsBtnClicked,
onSmsSend,
countdown,
};
}
vue文件
<template>
<div class="container">
<div class="main">
<div class="h2">{{ title }}</div>
<div class="form">
<div class="form-item">
<div class="form-item-country">中国 +86</div>
<van-field
v-model="mobile"
class="form-field"
:border="false"
type="tel"
placeholder="请输入手机号"
clearable
/>
</div>
<div class="form-item">
<van-field v-model="nick" class="form-field" :border="false" type="tel" placeholder="请输入昵称" clearable>
<template #right-icon>
<img class="icon-random" :src="randomIcon" alt="" @click="onNickRandom" />
</template>
</van-field>
</div>
<div class="form-item">
<van-field
v-model="smsCode"
class="form-field"
:border="false"
type="number"
placeholder="请输入4位验证码"
clearable
/>
<template v-if="smsTimer">
<span class="sms-btn countdown">{{ smsText }}</span>
</template>
<template v-else>
<span class="sms-btn" @click="onSmsBtnClicked">{{ smsText }}</span>
</template>
</div>
<div class="form-item">
<PwdField
key="pwd"
v-model="pwd"
class="form-field"
:border="false"
placeholder="请设置8-25位(数字+字母)密码"
clearable
/>
</div>
<div class="form-item">
<PwdField
key="pwd2"
v-model="pwd2"
class="form-field"
:border="false"
placeholder="请再次输入密码"
clearable
/>
</div>
<van-button
class="form-submit"
block
:disabled="!submitted"
:loading="submitLoading"
loading-text="注册中..."
type="primary"
@click="onSubmit"
>确定</van-button
>
</div>
</div>
<div class="footer">
<div class="footer-agreement">
<van-checkbox v-model="agree" icon-size="16px" />
<span> 阅读并同意</span><a href="javascript:void(0);">《用户协议》</a>和<a href="javascript:void(0);"
>《隐私政策d》</a
>
</div>
</div>
<!-- 图形验证码 -->
<Captcha v-model:show="captchaShow" @success="onSmsSend" />
</div>
</template>
<script lang="ts" setup>
import { computed, onMounted, ref, unref } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import { Toast } from 'vant';
import Captcha from '@/components/Captcha/index.vue';
import PwdField from '@/components/PwdField/index.vue';
import { nickList } from '@/constants/modules/user';
import { isMobile, isPassWord, isSame } from '@/utils/validate';
import { randomIntegerInRange } from '@/utils/lodash';
import randomIcon from '@/assets/icons/shaizi.svg';
import { useUserStore } from '@/store/modules/user';
import { useSmsCode } from '@/hooks/shared/useSmsCode';
const userStore = useUserStore();
onMounted(() => {
onNickRandom();
});
const router = useRouter();
const route = useRoute();
const title = ref('免费注册');
const { mobile, smsCode, smsTimer, smsText, captchaShow, onSmsBtnClicked, onSmsSend } = useSmsCode();
const pwd = ref('');
const pwd2 = ref('');
const nick = ref('');
function onNickRandom() {
nick.value = nickList[randomIntegerInRange(0, nickList.length - 1)];
}
const agree = ref(true);
const submitLoading = ref(false);
const submitted = computed(() => {
return unref(mobile) && unref(nick) && unref(smsCode) && unref(pwd) && unref(pwd2);
});
function onSubmit() {
if (!isMobile(unref(mobile))) {
Toast('手机号格式错误');
return;
}
if (!isPassWord(unref(pwd))) {
Toast('请设置8-25位(数字+字母)密码');
return;
}
if (!isSame(unref(pwd), unref(pwd2))) {
Toast('2次输入密码不一致');
return;
}
const params = {
mobile: unref(mobile),
code: unref(smsCode),
nick: unref(nick),
pwd: unref(pwd),
autoLogin: true,
};
submitLoading.value = true;
userStore
.login({ provider: 'register', params })
.then(() => {
submitLoading.value = false;
route.query.redirect ? router.replace({ path: route.query.redirect as string }) : router.replace({ path: '/' });
Toast.success('注册成功');
})
.catch((error) => {
submitLoading.value = false;
console.error(error);
});
}
</script>
<style lang="less" scoped>
</style>