182 lines
5.1 KiB
Vue
182 lines
5.1 KiB
Vue
<template>
|
||
<div class="login-form-container">
|
||
<div class="title">
|
||
<span style="color: #6777ef">Plusone </span>
|
||
<span style="font-weight: 300">Admin</span>
|
||
</div>
|
||
|
||
<n-form
|
||
ref="formRef"
|
||
:model="model"
|
||
:rules="rules"
|
||
:show-feedback="false"
|
||
:show-label="false"
|
||
size="large"
|
||
>
|
||
<n-form-item path="principal">
|
||
<n-input
|
||
placeholder="邮箱地址 / 手机号"
|
||
v-model:value="model.principal"
|
||
@keydown.enter.prevent
|
||
/>
|
||
</n-form-item>
|
||
|
||
<n-grid y-gap="24" :cols="24">
|
||
<n-gi :span="15">
|
||
<n-form-item path="password">
|
||
<n-input
|
||
placeholder="验证码"
|
||
v-model:value="model.otp"
|
||
@input="handlePasswordInput"
|
||
@keydown.enter.prevent
|
||
/>
|
||
</n-form-item>
|
||
</n-gi>
|
||
<n-gi :span="9">
|
||
<div style="display: flex; justify-content: flex-end">
|
||
<n-button
|
||
class="txt-btn"
|
||
@click="handleBtnGetOTPClick"
|
||
size="large"
|
||
style="width: 100%"
|
||
>
|
||
获取验证码
|
||
</n-button>
|
||
</div>
|
||
</n-gi>
|
||
</n-grid>
|
||
|
||
<n-grid y-gap="24" :cols="2">
|
||
<n-gi>
|
||
<n-form-item path="rememberMe">
|
||
<n-checkbox v-model:checked="model.rememberMe" size="large">
|
||
<span style="color: #808080">保持登录状态</span>
|
||
</n-checkbox>
|
||
</n-form-item>
|
||
</n-gi>
|
||
<n-gi>
|
||
<div style="display: flex; justify-content: flex-end">
|
||
<n-button class="txt-btn" text @click="$emit('toLoginByPassword')">
|
||
密码登录
|
||
</n-button>
|
||
</div>
|
||
</n-gi>
|
||
</n-grid>
|
||
|
||
<n-button
|
||
type="primary"
|
||
size="large"
|
||
style="width: 100%; margin-top: 8px"
|
||
@click="handleBtnLoginClick"
|
||
>
|
||
登录
|
||
</n-button>
|
||
|
||
<div style="display: flex; justify-content: flex-end; margin-top: 8px">
|
||
<n-button class="txt-btn" text style="margin-left: 16px"> 忘记密码 </n-button>
|
||
<n-button class="txt-btn" text style="margin-left: 16px"> 免费注册 </n-button>
|
||
</div>
|
||
</n-form>
|
||
</div>
|
||
</template>
|
||
|
||
<script lang="ts" setup>
|
||
import { ref } from 'vue'
|
||
import type { FormInst, FormItemInst, FormItemRule, FormRules } from 'naive-ui'
|
||
import { useMessage } from 'naive-ui'
|
||
|
||
interface LoginByPasswordCommand {
|
||
principal: string
|
||
otp: string
|
||
rememberMe: boolean
|
||
}
|
||
|
||
const formRef = ref<FormInst | null>(null)
|
||
const rPasswordFormItemRef = ref<FormItemInst | null>(null)
|
||
const message = useMessage()
|
||
const model = ref<LoginByPasswordCommand>({
|
||
principal: '',
|
||
otp: '',
|
||
rememberMe: false,
|
||
})
|
||
|
||
const rules: FormRules = {
|
||
principal: [
|
||
{
|
||
required: true,
|
||
validator(rule: FormItemRule, value: string) {
|
||
if (!value) {
|
||
return new Error('需要年龄')
|
||
} else if (!/^\d*$/.test(value)) {
|
||
return new Error('年龄应该为整数')
|
||
} else if (Number(value) < 18) {
|
||
return new Error('年龄应该超过十八岁')
|
||
}
|
||
return true
|
||
},
|
||
trigger: ['input', 'blur'],
|
||
},
|
||
],
|
||
otp: [
|
||
{
|
||
required: true,
|
||
message: '请输入密码',
|
||
},
|
||
],
|
||
}
|
||
|
||
function handlePasswordInput() {
|
||
if (model.value.rememberMe) {
|
||
rPasswordFormItemRef.value?.validate({ trigger: 'password-input' })
|
||
}
|
||
}
|
||
|
||
function handleBtnLoginClick(e: MouseEvent) {
|
||
e.preventDefault()
|
||
formRef.value?.validate((errors) => {
|
||
if (!errors) {
|
||
message.success('验证成功')
|
||
} else {
|
||
console.log(errors)
|
||
message.error('验证失败')
|
||
}
|
||
})
|
||
}
|
||
|
||
function handleBtnGetOTPClick() {
|
||
console.log('handleBtnGetOTPClick')
|
||
}
|
||
</script>
|
||
|
||
<style scoped>
|
||
.login-form-container {
|
||
width: 320px;
|
||
background-color: #f3f3f3;
|
||
padding: 32px 40px;
|
||
border-radius: 6px;
|
||
border: solid 1px #e4e4e4;
|
||
box-shadow: 0 4px 24px 0 rgba(0, 0, 0, 0.2);
|
||
border-top: solid 4px #6777ef;
|
||
}
|
||
|
||
.title {
|
||
font-size: 30px;
|
||
text-align: center;
|
||
margin-bottom: 16px;
|
||
}
|
||
|
||
.n-form-item {
|
||
margin-bottom: 8px;
|
||
}
|
||
|
||
.txt-btn {
|
||
line-height: 40px;
|
||
font-size: 15px;
|
||
color: #6777ef;
|
||
}
|
||
|
||
.txt-btn:hover {
|
||
color: rgba(103, 119, 239, 0.8);
|
||
}
|
||
</style>
|