效果图:
登录页面效果图
功能:
. 账号登录、验证码登录;
. 账号登录:记住密码。使用aes和ras给用户数据加密储存于localStorage;
. 验证码登录:手机号码为空时,获取验证码按钮为禁用状态;获取验证码按钮在成功点击后会启动倒计时,并同时转为禁用状态。
登录页代码:
<template>
<div class="login-frame">
<div class="login-body">
<NjxSwitchTab :list="tabList" @switch-tab="({index}) => tabActive = index" />
<div class="form-view">
<el-form v-if="tabActive === 0" size="large" ref="formCodeRef" :model="formCode" :rules="rulesCode">
<el-form-item prop="phone">
<el-input class="form-item" clearable :prefix-icon="User" v-model="formCode.phone" placeholder="请输入手机号码"
type="number" @keyup.enter="handleFocus(passwordRef)"></el-input>
</el-form-item>
<el-form-item prop="password">
<el-input class="form-item" :prefix-icon="Lock" v-model="formCode.password" placeholder="请输入密码" show-password @keyup.enter="handleLogin(formCodeRef)"
clearable ref="passwordRef"></el-input>
</el-form-item>
</el-form>
<el-form v-else size="large" ref="formVerifyRef" :model="formVerify" :rules="rulesVerify">
<el-form-item prop="phone">
<el-input type="number" class="form-item" v-model="formVerify.phone" placeholder="请输入手机号码" clearable :prefix-icon="Lock" @keyup.enter="handleFocus(verifyRef)"></el-input>
</el-form-item>
<el-form-item prop="verifyCode">
<el-input class="form-item" placeholder="请输入验证码" v-model="formVerify.verifyCode" ref="verifyRef" @keyup.enter="handleLogin(formVerifyRef)">
<template #append>
<el-button type="primary" @click="getVerifyCode" :disabled="disabledVerify">{{ verify.buttonText
}}</el-button>
</template>
</el-input>
</el-form-item>
</el-form>
<div class="form-operation clearboth">
<el-checkbox v-model="rememberPassword" label="记住密码" class="float_l" v-if="tabActive === 0" />
<div class="float_r" v-if="false">
<el-button type="primary" link>忘记密码</el-button>
<el-button type="primary" link>免费注册</el-button>
</div>
</div>
<el-button size="large" :disabled="disabledLoginButton" type="primary" class="w_100"
@click="handleLogin(tabActive === 0 ? formCodeRef : formVerifyRef)">登录</el-button>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { User, Lock } from "@element-plus/icons-vue";
import { FormInstance, FormRules } from "element-plus";
import Router from "@/router"
import { validMobile, validPassword } from "@/utils/utils"
import {njxEncode, njxDecode} from "@/utils/ancode"
// 账号登录
const formCode = ref({
phone: "",
password: "",
});
const validPhone = (rule: any, value: string, callback: any) => {
if (!value) {
return callback(new Error("请输入电话号码"));
} else if (!validMobile(value)) {
return callback(new Error("请输入真实手机号码"));
} else {
callback();
}
}
const validPswd = (rule: any, value: string, callback: any) => {
if (!value) {
return callback(new Error("请输入密码"));
} else if (!validPassword(value)) {
return callback(new Error("请输入6~14位包含字母和数字的密码"))
} else {
callback();
}
}
const rulesCode = reactive<FormRules>({
phone: [{ required: true, trigger: "blur", validator: validPhone }],
password: [{ required: true, trigger: "blur", validator: validPswd }],
})
// 验证码登录
const formVerify = ref({
phone: "",
verifyCode: ""
})
const rulesVerify = reactive<FormRules>({
phone: [{ required: true, trigger: "blur", validator: validPhone }],
verifyCode: [{ required: true, trigger: "blur", message: "请输入验证码" }]
})
const formCodeRef = ref<FormInstance>();
const formVerifyRef = ref<FormInstance>();
const passwordRef = ref()
const verifyRef = ref();
const rememberPassword = ref(false);
const disabledLoginButton = computed(() => {
const tab1 = !formCode.value.phone || !formCode.value.password;
const tab2 = !formVerify.value.phone || !formVerify.value.verifyCode;
return tabActive.value === 0 ? tab1 : tab2;
})
const handleLogin = (formEl: FormInstance | undefined) => {
if(!formEl) return;
formEl.validate((valid) => {
if(!valid) return;
ElNotification({
title: "登录成功~~立即跳转首页。账号: ",
message: tabActive.value === 0 ? formCode.value.phone : formVerify.value.phone,
})
// 记住密码
if(rememberPassword.value) {
const params = tabActive.value === 0 ? JSON.stringify(formCode.value) : JSON.stringify(formVerify);
const {key, data} = njxEncode(params);
localStorage.setItem("NJX_LOGININFO_KEY", key);
localStorage.setItem("NJX_LOGININFO_CONTENT", data);
}
setTimeout(() => {
Router.push("/")
}, 1400)
})
};
// 切换登录方式
const tabActive = ref(0);
const tabList = [
{
label: "账号登录",
},
{
label: "验证码登录",
},
];
const handleFocus = (formEl: any) => {
if (!formEl) return;
formEl.focus();
}
// 验证码
const resetCount = () => {
clearInterval(timer);
timer = 0;
};
let timer: number = 0;
const verify = reactive({
count: 11,
buttonText: "获取验证码",
});
const disabledVerify = computed(() => {
return !formVerify.value.phone || verify.count <= 10;
});
const getVerifyCode = () => {
// 校验手机号码
if(!validMobile(formVerify.value.phone)) return;
ElMessage.success("验证码发送成功,请查看");
verify.count--;
verify.buttonText = verify.count + " 秒后重新获取验证码";
timer = window.setInterval(() => {
if (verify.count <= 1) {
resetCount();
verify.buttonText = "重新发送验证码";
verify.count = 11;
return;
}
verify.count--;
verify.buttonText = verify.count + " 秒后重新获取验证码";
}, 1000);
};
const handleRemember = () => {
const clearStorage = () => {
localStorage.removeItem("NJX_LOGININFO_KEY");
localStorage.removeItem("NJX_LOGININFO_CONTENT");
rememberPassword.value = false;
}
const content = localStorage.getItem("NJX_LOGININFO_CONTENT");
const key = localStorage.getItem("NJX_LOGININFO_KEY");
// 没有保存内容
if(!content || !key) {
clearStorage();
return;
};
const {res} = njxDecode(content, key);
if(!res) {
clearStorage();
} else {
formCode.value = JSON.parse(res);
rememberPassword.value = true;
}
}
onMounted(() => {
resetCount();
handleRemember();
});
</script>
<style lang="scss" scoped>
.login-frame {
width: 320px;
height: 100%;
margin: auto;
}
.login-body {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.form-view {
width: 100%;
height: 200px;
}
.form-item {
margin-top: 20px;
}
.form-operation {
height: 50px;
line-height: 50px;
}
.el-input-group__append button.el-button {
color: $primary;
}
.el-input-group__append button.el-button.is-disabled {
color: #c1c1c1 !important;
}
.el-form-item--large {
margin-bottom: 0;
}
</style>
加解密代码请查看 vue ---- 使用rsa和aes给接口加解密
tada~~~一个有“记住密码”和“获取验证码”的登录页面就完成啦~
网友评论