hookehuyr

🦄 refactor: 登录页面逻辑写法重构

/*
* @Date: 2022-06-22 00:07:42
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2022-06-22 01:28:42
* @FilePath: /tswj/src/composables/useLogin.js
* @Description: 文件描述
*/
import { bLoginAPI } from '@/api/B/login'
import { useRouter } from 'vue-router'
import { wxInfo } from '@/utils/tools';
import { ref } from 'vue'
import { useCountDown } from '@vant/use';
import { smsAPI } from '@/api/common'
import { Toast } from 'vant'
export const useLogin = () => {
const phone = ref('');
const code = ref('')
const form = ref(null);
const submit = () => {
let valid = form.value.validate();
valid
.then(() => {
form.value.submit();
})
.catch(error => {
console.error(error);
Toast({
message: '请检查后再次提交',
icon: 'cross',
});
})
}
/**
* 判断微信环境看是否弹出控件框
* 桌面微信直接输入
* 其他环境弹出输入框
*/
let use_widget = ref(true);
use_widget.value = !!(wxInfo().isiOS || wxInfo().isAndroid);
const disabled = ref(true);
/**
* 手机号码校验
* 函数返回 true 表示校验通过,false 表示不通过
* @param {*} val
*/
const validator = (val) => {
let flag = false;
// 简单判断手机号位数
if (/1\d{10}/.test(val) && phone.value.length === 11) {
disabled.value = false;
flag = true;
} else {
disabled.value = true;
flag = false;
}
return flag
};
/**
* 数字弹框
*/
const keyboard_show = ref(false);
const refPhone = ref(null)
const showKeyboard = () => { // 弹出数字弹框
keyboard_show.value = true;
};
const keyboardBlur = () => { // 数字键盘失焦回调
keyboard_show.value = false;
refPhone.value.validate();
};
// 设置发送短信倒计时
// TAG: vant 自带倒计时函数
const limitSeconds = ref(60000); // 配置倒计时秒数
const countDown = useCountDown({ // 配置倒计时
time: limitSeconds.value,
onFinish: () => {
countDown.reset();
}
});
const sendCode = async () => { // 发送验证码
countDown.start();
// 验证码接口
const { code } = await smsAPI({ phone: phone.value });
if (code) {
Toast.success('发送成功');
}
};
// 过滤输入的数字 只能四位
const formatter = (value) => value.substring(0, 4);
/**
* 用户登录
* @param {*} values
*/
const $router = useRouter();
const onSubmit = async (values) => {
const { code } = await bLoginAPI({ phone: values.phone, pin: values.code })
if (code) {
$router.push({
path: '/business/index'
});
}
};
return {
phone,
code,
onSubmit,
use_widget,
disabled,
validator,
keyboardBlur,
keyboard_show,
showKeyboard,
refPhone,
form,
submit,
formatter,
limitSeconds,
countDown,
sendCode,
}
}
/*
* @Author: hookehuyr hookehuyr@gmail.com
* @Date: 2022-05-25 18:34:17
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2022-06-22 01:35:44
* @FilePath: /tswj/src/theme-vars.js
* @Description: 修改vant默认表单样式
*/
import { styleColor } from '@/constant.js';
export const loginTheme = {
buttonPrimaryBackground: styleColor.baseColor,
buttonPrimaryBorderColor: styleColor.baseColor,
buttonPrimaryColor: styleColor.baseFontColor,
CellVerticalPadding: '14px'
};
......@@ -10,14 +10,18 @@
</van-row>
</div>
<div class="login-section">
<van-config-provider :theme-vars="themeVars">
<van-config-provider :theme-vars="loginTheme">
<van-form ref="form" @submit="onSubmit">
<van-cell-group inset style="border: 1px solid #EAEAEA;">
<van-field v-if="use_widget" v-model="phone" name="phone" label="手机号" placeholder="手机号" readonly clickable :rules="[{ validator, message: '请输入正确手机号' }]" @touchstart.stop="showKeyboard" />
<van-field v-else v-model="phone" name="validator" label="手机号" placeholder="手机号" :rules="[{ validator, message: '请输入正确手机号' }]" />
<van-field v-model="code" center clearable name="code" type="digit" label="短信验证码" placeholder="请输入短信验证码" :formatter="formatter" :rules="[{ required: true, message: '请填写验证码' }]">
<van-field v-if="use_widget" ref="refPhone" v-model="phone" name="phone" label="手机号" placeholder="手机号"
readonly clickable :rules="[{ validator, message: '请输入正确手机号' }]" @touchstart.stop="showKeyboard" />
<van-field v-else v-model="phone" name="validator" label="手机号" placeholder="手机号"
:rules="[{ validator, message: '请输入正确手机号', trigger: 'onBlur' }]" />
<van-field v-model="code" center clearable name="code" type="digit" label="短信验证码" placeholder="请输入短信验证码"
:formatter="formatter" :rules="[{ required: true, message: '请填写验证码' }]">
<template #button>
<van-button v-if="countDown.current.value.total === limit" size="small" type="primary" :disabled="disabled" @click="sendCode">
<van-button v-if="countDown.current.value.total === limitSeconds" size="small" type="primary"
:disabled="disabled" @click="sendCode">
<span>发送验证码</span>
</van-button>
<van-button v-else size="small" type="primary" :disabled="disabled">
......@@ -33,7 +37,7 @@
登&nbsp;录
</div>
<van-number-keyboard v-model="phone" :show="keyboard_show" :maxlength="11" @blur="onBlur" />
<van-number-keyboard v-model="phone" :show="keyboard_show" :maxlength="11" @blur="keyboardBlur" />
<!-- 图片滑块验证 -->
<image-slider-verify :is-show="sliderShow" @done="handleConfirm" @on-close="handleClose" />
......@@ -42,59 +46,22 @@
<script setup>
import Cookies from 'js-cookie'
import ImageSliderVerify from '@/components/ImageSliderVerify/index.vue'
import { styleColor } from '@/constant.js';
import { loginTheme } from '@/theme-vars.js';
import { ref, onMounted } from 'vue';
import { Toast } from 'vant'
import { useRouter } from 'vue-router'
import logo_image from '@images/denglu-top@2x.png'
import { wxInfo } from '@/utils/tools';
import { useCountDown } from '@vant/use';
import { smsAPI } from '@/api/common'
import { bLoginAPI } from '@/api/B/login'
import { useLogin } from '@/composables/useLogin';
const { phone, code, onSubmit, use_widget, validator, keyboardBlur, disabled, keyboard_show, refPhone, showKeyboard, form, submit, formatter, limitSeconds, countDown, sendCode, } = useLogin();
const $router = useRouter();
// 判断是否显示控件
let use_widget = ref(true);
/**
* 手机号码校验
* 函数返回 true 表示校验通过,false 表示不通过
* @param {*} val
*/
const validator = (val) => {
let flag = false;
// 简单判断手机号位数
if (/1\d{10}/.test(val) && phone.value.length === 11) {
disabled.value = false;
flag = true;
} else {
disabled.value = true;
flag = false;
}
return flag
};
const phone = ref('');
const code = ref('');
// TAG: 开发环境测试数据
if (import.meta.env.DEV) {
phone.value = import.meta.env.VITE_ID
code.value = import.meta.env.VITE_PIN
}
const form = ref(null);
onMounted(() => {
/**
* 判断微信环境看是否弹出控件框
* 桌面微信直接输入
* 其他环境弹出输入框
*/
use_widget.value = !!(wxInfo().isiOS || wxInfo().isAndroid);
// 判断微信授权状态,进入页面时未授权需要授权跳转
if (!Cookies.get('PHPSESSID')) {
$router.replace({
......@@ -107,91 +74,6 @@ onMounted(() => {
}
})
const submit = () => {
let valid = form.value.validate();
valid
.then(() => {
form.value.submit();
})
.catch(error => {
console.error(error);
Toast({
message: '请检查后再次提交',
icon: 'cross',
});
})
}
// 手机号输入控件控制
const keyboard_show = ref(false);
const showKeyboard = () => { // 弹出数字弹框
keyboard_show.value = true;
};
const onBlur = () => { // 数字键盘失焦回调
keyboard_show.value = false;
if (phone.value.length === 11) {
disabled.value = false;
}
};
// 设置发送短信倒计时
// const countDown = ref(60);
// const countDownHandle = () => {
// // 倒计时
// if (countDown.value === 0) {
// countDown.value = 60;
// } else {
// countDown.value--;
// setTimeout(() => {
// countDownHandle()
// }, 1000)
// }
// }
// 设置发送短信倒计时
// TAG: vant 自带倒计时函数
const limit = ref(60000); // 配置倒计时秒数
const countDown = useCountDown({ // 配置倒计时
time: limit.value,
onFinish: () => {
countDown.reset();
}
});
const sendCode = async () => { // 发送验证码
countDown.start();
// 验证码接口
const { code } = await smsAPI({ phone: phone.value });
if (code === 1) {
Toast.success('发送成功');
}
};
const disabled = ref(true);
// 过滤输入的数字 只能四位
const formatter = (value) => value.substring(0, 4);
/**
* 用户登录
* @param {*} values
*/
const onSubmit = async (values) => {
const { code } = await bLoginAPI({ phone: values.phone, pin: values.code })
if (code === 1) {
$router.push({
path: '/business/index'
});
}
};
const themeVars = {
buttonPrimaryBackground: styleColor.baseColor,
buttonPrimaryBorderColor: styleColor.baseColor,
buttonPrimaryColor: styleColor.baseFontColor,
CellVerticalPadding: '14px'
};
// 滑块验证成功后回调
const sliderShow = ref(false);
const handleConfirm = (val) => {
......