任务介绍
本周实现登陆注册功能。
由于本项目主要关注在数据集的相关操作,所以对于用户的登录注册验证没有必要采取完整的一套手机号(邮箱)验证机制,简单的实现一个注册和登录功能即可。
背景效果
首先展示效果
整体背景页面和中部框的背景框都使用了玻璃模糊效果来避免遮蔽关键数据。
/*内部框css,使用伪元素::before结合filter实现毛玻璃*/
.overlay::before {
background: url("../../img/loginInnerBG.jpg");
content: "";
width: 100%;
height: 100%;
position: absolute;
left: 0;
top: 0;
/* background: inherit; */
background-size: cover;
filter: blur(2px);
z-index: -1;
}
.mybody {
align-items: center;
background-color: var(--white);
/* background-image: url("https://www.todaybing.com/api/today/cn"); */
background-image: url("https://bing.img.run/rand_uhd.php");
background-attachment: fixed;
background-position: center;
background-repeat: no-repeat;
background-size: cover;
display: grid;
height: 100vh;
place-items: center;
}
.mybody::before {
content: "";
position: absolute; /* 一定要用绝对定位 */
width: 100%;
height: 100%;
backdrop-filter: blur(4px); /* 模糊半径 */
}
整体背景同样使用before+filter实现模糊效果。同时使用一个微软的随机壁纸实现随机背景。
切换效果
切换效果是基于css3的transform实现的,我们定义一个状态theName,当theName为0的时候应该展示登录页面,否则应该展示注册页面。对于这两个页面展示的区分比较好控制。只要判断一下theName的值,然后决定遮罩层的位置即可。
但是我们还需要实现遮罩层移动时的动画。这里我们使用css3的transform实现。为顶层元素定义一个与theName相关的class。
<div
className={
theName === 0 ? "container right-panel-active" : "container"
}
>
content...
</div>
然后我们在css中为不同的类定义不同的X轴偏移,这样css就会在类名切换时自动实现切换动画。
.container.right-panel-active .container__overlay {
transform: translateX(-100%);
}
登录注册逻辑
登录注册使用一个状态维护用户输入值,然后使用已经封装好的react-query函数发起调用即可。
然后监听一下请求状态,当登录成功的时候,把用户token和id信息等关键信息保存到localstroage中去。注册成功后则切换状态,使用户进入登录页面。
const Login = () => {
//实现登录接口
if (loginUserName === "" || loginUserPsw === "") {
enqueueSnackbar("账号密码不能为空", { variant: "warning" });
return;
}
loginMutate({
url: login_url,
method: "post",
data: {
name: loginUserName,
passwd: loginUserPsw,
},
});
};
const handleReset = () => {
if (vertifyCode == "") {
enqueueSnackbar("请填写密码", { variant: "warning" });
return;
}
if (email == "") {
enqueueSnackbar("邮箱不能为空", { variant: "warning" });
return;
}
if (loginUserName == "") {
enqueueSnackbar("用户名不能为空", { variant: "warning" });
return;
}
signUpMutate({
url: signUP_url,
data: {
name: loginUserName,
passwd: vertifyCode,
email: email,
avatar: "http://t",
},
method: "post",
});
};
useEffect(() => {
if (signUpSuccess) {
enqueueSnackbar("注册成功,请登录", { variant: "success" });
changeClass();
}
}, [signUpSuccess]);
const innerTheme = useMemo(() =>
createTheme({
palette: {
mode: "light",
},
})
);
useEffect(() => {
if (loginSuccess) {
if (loginData.data.code !== 200) {
enqueueSnackbar(loginData.data.msg, { variant: "error" });
return;
} else {
console.log(loginData.data);
localStorage.setItem("token", "Bearer " + loginData.data.data.token);
localStorage.setItem("name", loginUserName);
localStorage.setItem("userId", loginData.data.data.user.ID);
localStorage.setItem("avatar", loginData.data.data.user.avatar);
navigate("/workshop");
}
}
}, [loginSuccess]);