Files
miaoBlog/pages/user/login.vue
T

224 lines
5.8 KiB
Vue

<template>
<div class="login-warpper">
<div class="login-card">
<div class="login-logo">
<cat></cat>
</div>
<!-- <div>杪Blog后台</div> -->
<div class="login-form">
<el-input class="login-form-input" v-model="username" placeholder="用户名" />
<el-input class="login-form-input" v-model="password" placeholder="密码" type="password" show-password />
<div :class="['login-form-message', `login-form-message-${message.type}`]">
<span>{{ message.message }}</span>
<nuxt-link to="/user/register">注册账户</nuxt-link>
</div>
<div class="login-form-button-warpper">
<el-button class="login-form-button" @click="handleLogin">
登 录
</el-button>
</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import useUserStore from '~/hooks/pinia/useUserStore';
import cat from '~/components/icons/cat.vue';
import useMiaoFetch from '~/hooks/useMiaoFetch';
const { user: { login } } = useMiaoFetch()
const router = useRouter()
const userStore = useUserStore()
const username = ref('')
const password = ref('')
let isLogining = false
const message = ref({
type: 'warning',
message: ''
})
watch(() => username.value + password.value, () => {
message.value = {
type: 'default',
message: '',
}
})
const handleLogin = async () => {
if (isLogining) return
if (username.value === '' || password.value === '') {
message.value = {
type: 'warning',
message: '用户名或密码不能为空'
}
return
}
isLogining = true
message.value = {
type: 'default',
message: '登录中...'
}
try {
const res = await login({
username: username.value,
password: password.value
})
isLogining = false
message.value = {
type: 'default',
message: '登录成功'
}
userStore.setLoginStatus(true)
userStore.setToken(res.token)
userStore.setTokenExpireTime(res.expiresIn)
router.push('/user')
} catch (e) {
isLogining = false
// @ts-ignore
const code = e.statusCode ?? undefined
console.log(code, code === 401)
if (code === 401) {
message.value = {
type: 'warning',
message: '用户名或密码错误'
}
} else {
message.value = {
type: 'warning',
message: '登录失败'
}
}
}
}
onBeforeMount(() => {
if (userStore.isLogin === true) {
return router.push('/user')
}
})
</script>
<style lang="scss" scoped>
.login-warpper {
width: 100%;
margin: 0 auto;
min-height: calc(100vh - 60px);
display: flex;
flex-direction: column;
justify-content: center;
.login-card {
position: relative;
width: 300px;
// aspect-ratio: 9/16;
border-radius: 20px;
margin: auto;
box-shadow: rgba(50, 50, 93, 0.25) 0px 30px 60px -12px inset, rgba(0, 0, 0, 0.3) 0px 18px 36px -18px inset;
.login-logo {
width: 100px;
height: 100px;
// aspect-ratio: 1;
display: flex;
justify-content: center;
align-items: center;
margin: 80px auto 40px;
svg {
width: 100%;
aspect-ratio: 1;
}
}
.login-form {
width: 180px;
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: center;
gap: 15px;
margin: 40px auto 80px;
&-message {
margin: -10px 0 0px;
width: 100%;
text-align: left;
font-size: 10px;
user-select: none;
display: flex;
justify-content: space-between;
&-warning {
color: #f56c6c;
}
&-default {
color: #15aa87;
}
& > a {
color: #15aa87;
text-decoration: none;
}
}
&-input {
padding: 0;
width: 100%;
--el-input-focus-border-color: #15aa87;
--el-input-hover-border-color: #15aa875d;
}
&-button-warpper {
.login-form-button {
width: 150px;
--el-button-active-border-color: #15aa87;
--el-button-hover-border-color: #15aa875d;
--el-button-hover-bg-color: #ffffff;
--el-button-hover-text-color: #15aa87;
--el-button-outline-color: #15aa87a0;
}
}
}
}
// &::before {
// content: '';
// display: block;
// width: 20vw;
// aspect-ratio: 1;
// border-radius: 50%;
// background-color: aqua;
// position: absolute;
// top: 0;
// left: 40%;
// }
// &::after {
// content: '';
// display: block;
// width: 20vw;
// aspect-ratio: 1;
// border-radius: 50%;
// background-color: rgb(35, 191, 79);
// position: absolute;
// bottom: 0;
// left: 40%;
// }
}
</style>
<style>
/* .login-form-input .el-input__wrapper {
transition: box-shadow .3s ease;
}
.login-form-input .el-input__wrapper.is-focus {
box-shadow: 0 0 0 1px #15aa87 !important;
} */
</style>