127 lines
2.6 KiB
Vue
127 lines
2.6 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">
|
|
<input
|
|
v-model="localAccount"
|
|
class="login-form__input"
|
|
type="text"
|
|
placeholder="请输入账号"
|
|
autocomplete="username"
|
|
>
|
|
</div>
|
|
<div class="login-form__field">
|
|
<input
|
|
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>已阅读并同意《用户协议》和《隐私政策》</span>
|
|
</label>
|
|
<button class="login-form__submit" type="submit">
|
|
登 录
|
|
</button>
|
|
</form>
|
|
</template>
|
|
|
|
<style lang="less" scoped>
|
|
.login-form {
|
|
.flex(column, flex-start);
|
|
gap: @spacing-base;
|
|
|
|
&__field {
|
|
width: 100%;
|
|
}
|
|
|
|
&__input {
|
|
width: 100%;
|
|
height: 44px;
|
|
padding: 0 @spacing-base;
|
|
border: 1px solid @border-color;
|
|
border-radius: @radius-base;
|
|
background: @bg-color-light;
|
|
font-size: @font-size-base;
|
|
color: @heading-color;
|
|
outline: none;
|
|
transition: border-color 0.2s;
|
|
box-sizing: border-box;
|
|
|
|
&:focus {
|
|
border-color: @primary-color;
|
|
}
|
|
|
|
&::placeholder {
|
|
color: @text-color-secondary;
|
|
}
|
|
}
|
|
|
|
&__agree {
|
|
.flex(row, flex-start);
|
|
gap: @spacing-xs;
|
|
font-size: @font-size-sm;
|
|
color: @text-color-secondary;
|
|
cursor: pointer;
|
|
|
|
input {
|
|
margin-top: 2px;
|
|
accent-color: @primary-color;
|
|
}
|
|
}
|
|
|
|
&__submit {
|
|
width: 100%;
|
|
height: 44px;
|
|
border: none;
|
|
border-radius: @radius-base;
|
|
background: @primary-color;
|
|
color: @white;
|
|
font-size: @font-size-lg;
|
|
letter-spacing: 2px;
|
|
cursor: pointer;
|
|
transition: background 0.2s;
|
|
|
|
&:hover {
|
|
background: @primary-hover;
|
|
}
|
|
}
|
|
}
|
|
</style>
|