170 lines
4.0 KiB
Vue
170 lines
4.0 KiB
Vue
<script setup lang="ts">
|
||
import { computed } from 'vue'
|
||
|
||
interface Props {
|
||
account: string
|
||
password: string
|
||
agree: boolean
|
||
}
|
||
|
||
const props = defineProps<Props>()
|
||
|
||
const emit = defineEmits<{
|
||
'update:account': [value: string]
|
||
'update:password': [value: string]
|
||
'update:agree': [value: boolean]
|
||
submit: []
|
||
}>()
|
||
|
||
const localAccount = computed({
|
||
get: () => props.account,
|
||
set: (value: string) => emit('update:account', value),
|
||
})
|
||
|
||
const localPassword = computed({
|
||
get: () => props.password,
|
||
set: (value: string) => emit('update:password', value),
|
||
})
|
||
|
||
const localAgree = computed({
|
||
get: () => props.agree,
|
||
set: (value: boolean) => emit('update:agree', value),
|
||
})
|
||
</script>
|
||
|
||
<template>
|
||
<form class="login-form" @submit.prevent="emit('submit')">
|
||
<div class="login-form__field">
|
||
<label class="login-form__label" for="login-account">账号</label>
|
||
<input
|
||
id="login-account"
|
||
v-model="localAccount"
|
||
class="login-form__input"
|
||
type="text"
|
||
placeholder="请输入账号"
|
||
autocomplete="username"
|
||
>
|
||
</div>
|
||
<div class="login-form__field">
|
||
<label class="login-form__label" for="login-password">密码</label>
|
||
<input
|
||
id="login-password"
|
||
v-model="localPassword"
|
||
class="login-form__input"
|
||
type="password"
|
||
placeholder="请输入密码"
|
||
autocomplete="current-password"
|
||
>
|
||
</div>
|
||
<label class="login-form__agree">
|
||
<input v-model="localAgree" type="checkbox">
|
||
<span>已阅读并同意<em>《用户协议》</em>和<em>《隐私政策》</em></span>
|
||
</label>
|
||
<button class="login-form__submit" type="submit">
|
||
登录
|
||
</button>
|
||
</form>
|
||
</template>
|
||
|
||
<style lang="less" scoped>
|
||
// 设计稿 #36(账号密码登录)纵向坐标:
|
||
// 账号标签 457 → 密码标签 585(差 128)
|
||
// 密码输入框底 ~648 → 勾选行 641 区间 → 登录按钮文字 688
|
||
// 表单左边界与 title 内缩对齐:1032.5 - 982.5(title 层中心对齐后) ≈ 0,
|
||
// 实测 title padding-left 17px 抵消 693/714 的差,故表单不再额外内缩。
|
||
.login-form {
|
||
.flex(column, flex-start, stretch);
|
||
margin: 26px 0 0;
|
||
width: 100%;
|
||
|
||
&__field {
|
||
.flex(column, flex-start, stretch);
|
||
// 标签底 474 → 输入框顶 480,间距 6px
|
||
gap: 6px;
|
||
width: 100%;
|
||
}
|
||
|
||
// 第一个字段底(480+40=520)→ 第二个字段标签顶 585,间距 65px
|
||
&__field + &__field {
|
||
margin-top: 65px;
|
||
}
|
||
|
||
&__label {
|
||
font-size: 13px;
|
||
font-weight: 500;
|
||
line-height: 17px;
|
||
color: #1f2937;
|
||
text-align: center;
|
||
}
|
||
|
||
&__input {
|
||
width: 100%;
|
||
height: 40px;
|
||
padding: 0 12px;
|
||
border: 1px solid @border-color;
|
||
border-radius: @radius-sm;
|
||
background: @white;
|
||
font-size: 13px;
|
||
color: #1f2937;
|
||
outline: none;
|
||
transition: border-color 0.2s;
|
||
box-sizing: border-box;
|
||
|
||
&:focus {
|
||
border-color: @primary-strong;
|
||
}
|
||
|
||
&::placeholder {
|
||
color: #1f2937;
|
||
}
|
||
}
|
||
|
||
// 设计稿 #36:勾选框 (1042.2,642) 7.5×14,文字 12px 起于 x=1059。
|
||
// 注:设计稿勾选标注 y=642 与密码输入框底 648 重叠,二者无法同时满足,
|
||
// 这里按视觉取勾选行落在输入框下方 8px。
|
||
&__agree {
|
||
.flex(row, flex-start, center);
|
||
gap: 8px;
|
||
margin-top: 8px;
|
||
font-size: 12px;
|
||
font-weight: 400;
|
||
line-height: 16px;
|
||
color: #6b7280;
|
||
cursor: pointer;
|
||
|
||
input {
|
||
flex-shrink: 0;
|
||
width: 14px;
|
||
height: 14px;
|
||
margin: 0;
|
||
accent-color: @primary-strong;
|
||
}
|
||
|
||
em {
|
||
font-style: normal;
|
||
color: @primary-strong;
|
||
}
|
||
}
|
||
|
||
// 设计稿 #36:按钮文字 (1352,688) 54×20 居中,按钮盒约 693×46
|
||
&__submit {
|
||
width: 100%;
|
||
height: 46px;
|
||
// 勾选行底 657 → 按钮顶 674
|
||
margin-top: 17px;
|
||
border: none;
|
||
border-radius: @radius-sm;
|
||
background: @primary-strong;
|
||
color: @white;
|
||
font-size: 15px;
|
||
font-weight: 500;
|
||
cursor: pointer;
|
||
transition: background 0.2s;
|
||
|
||
&:hover {
|
||
background: @primary-hover;
|
||
}
|
||
}
|
||
}
|
||
</style>
|