feat 搭建架构骨架
This commit is contained in:
145
src/views/login/cpns/SmsLoginForm.vue
Normal file
145
src/views/login/cpns/SmsLoginForm.vue
Normal file
@@ -0,0 +1,145 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { SmsCodeInput } from '@/components'
|
||||
import { isPhone } from '@/utils/validate'
|
||||
|
||||
interface Props {
|
||||
phone: string
|
||||
code: string
|
||||
agree: boolean
|
||||
}
|
||||
|
||||
const props = defineProps<Props>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
'update:phone': [value: string]
|
||||
'update:code': [value: string]
|
||||
'update:agree': [value: boolean]
|
||||
getCode: [phone: string]
|
||||
submit: []
|
||||
}>()
|
||||
|
||||
const localPhone = computed({
|
||||
get: () => props.phone,
|
||||
set: (value: string) => emit('update:phone', value),
|
||||
})
|
||||
|
||||
const localCode = computed({
|
||||
get: () => props.code,
|
||||
set: (value: string) => emit('update:code', value),
|
||||
})
|
||||
|
||||
const localAgree = computed({
|
||||
get: () => props.agree,
|
||||
set: (value: boolean) => emit('update:agree', value),
|
||||
})
|
||||
|
||||
function onGetCode(): void {
|
||||
if (!isPhone(props.phone)) {
|
||||
ElMessage.warning('手机号格式不正确')
|
||||
return
|
||||
}
|
||||
emit('getCode', props.phone)
|
||||
}
|
||||
|
||||
function onSubmit(): void {
|
||||
if (!isPhone(props.phone)) {
|
||||
ElMessage.warning('手机号格式不正确')
|
||||
return
|
||||
}
|
||||
if (!props.code) {
|
||||
ElMessage.warning('请输入验证码')
|
||||
return
|
||||
}
|
||||
emit('submit')
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<form class="sms-login" @submit.prevent="onSubmit">
|
||||
<div class="sms-login__field">
|
||||
<input
|
||||
v-model="localPhone"
|
||||
class="sms-login__input"
|
||||
type="text"
|
||||
placeholder="请输入手机号"
|
||||
maxlength="11"
|
||||
autocomplete="tel"
|
||||
>
|
||||
</div>
|
||||
<div class="sms-login__field">
|
||||
<SmsCodeInput v-model:code="localCode" @get-code="onGetCode" />
|
||||
</div>
|
||||
<label class="sms-login__agree">
|
||||
<input v-model="localAgree" type="checkbox">
|
||||
<span>已阅读并同意《用户协议》和《隐私政策》</span>
|
||||
</label>
|
||||
<button class="sms-login__submit" type="submit">
|
||||
登 录
|
||||
</button>
|
||||
</form>
|
||||
</template>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.sms-login {
|
||||
.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>
|
||||
Reference in New Issue
Block a user