本文已参与「新人创作礼」活动,一起开启掘金创作之路
设计一个登录页面
本文初始代码是这个地址:juejin.cn/post/697210…
我采用的大部分代码来自于这个地址:juejin.cn/post/697246…
话不多说,show me the code,这里直接将login/index.vue覆盖如下
<template>
<div class="login-wrapper">
<div :class="['login-container', loginActive ? 'active' : '']">
<div class="switch-wrapper row aCenter jCenter">
<div class="btn-wrapper row aCenter jCenter">
<div
v-if="loginActive"
class="txt row aCenter jCenter"
@click="loginActive = !loginActive"
>
去注册
</div>
<div v-else class="txt row aCenter jCenter" @click="loginActive = !loginActive">
去登录
</div>
</div>
</div>
<div :class="['outerBox', loginActive ? 'active' : '']">
<div class="container row aCenter jCenter">
<div class="login" v-show="loginActive">
<el-form :model="loginModel" status-icon :rules="loginRules" ref="loginRef">
<div class="title">登录</div>
<el-form-item prop="username">
<el-input
type="text"
placeholder="请输入账号 / 手机号 / 邮箱"
v-model="loginModel.username"
/>
</el-form-item>
<el-form-item prop="password">
<el-input type="password" placeholder="请输入密码" v-model="loginModel.password" />
</el-form-item>
<el-form-item>
<el-button type="primary" class="btn-login" @click="handleLogin">登录</el-button>
</el-form-item>
</el-form>
</div>
<div class="register" v-show="!loginActive">
<el-form :model="registerModel" status-icon :rules="registerRules" ref="registerRef">
<div class="title">注册</div>
<el-form-item prop="username">
<el-input
type="text"
placeholder="请输入账号 / 手机号 / 邮箱"
v-model="registerModel.username"
/>
</el-form-item>
<el-form-item prop="email">
<el-input type="text" placeholder="请输入邮箱地址" v-model="registerModel.email" />
</el-form-item>
<el-form-item prop="mobile">
<el-input
placeholder="请输入手机号码"
v-model.number="registerModel.mobile"
style="width: 100%"
/>
</el-form-item>
<el-form-item prop="password">
<el-input
type="password"
placeholder="请输入密码"
v-model="registerModel.password"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" class="btn-login" @click="handleRegister">
确认注册
</el-button>
</el-form-item>
</el-form>
</div>
</div>
</div>
</div>
</div>
</template>
<script lang="ts" setup>
import { ref, reactive } from 'vue'
const loginActive = ref(false)
const loginModel = reactive({ username: undefined, password: undefined })
const registerModel = reactive({
username: undefined,
email: undefined,
mobile: undefined,
password: undefined
})
const checkEmail = (_rule: any, value: any, callback: any) => {
if (!value) {
callback('请输入邮箱')
}
if (!/^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/.test(value)) {
callback(new Error('邮箱格式不正确'))
} else {
callback()
}
}
const checkMobile = (_rule: any, value: any, callback: any) => {
if (!value) {
callback('请输入手机号')
}
if (!/^(13[0-9]|14[5|7]|15[0|1|2|3|4|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9])\d{8}$/.test(value)) {
callback(new Error('手机号格式不正确'))
} else {
callback()
}
}
const loginRules = {
username: [{ required: true, message: '请输入用户名', trigger: 'blur' }],
password: [{ required: true, message: '请输入密码', trigger: 'blur' }]
}
const registerRules = {
username: [{ required: true, message: '请输入用户名', trigger: 'blur' }],
password: [{ required: true, message: '请输入密码', trigger: 'blur' }],
mobile: [{ required: true, validator: checkMobile, trigger: 'blur' }],
email: [{ required: true, validator: checkEmail, trigger: 'blur' }]
}
const loginRef = ref()
const registerRef = ref()
const handleLogin = () => {
loginRef.value.validate((vaild) => {
if (vaild) {
console.log(1)
}
})
}
const handleRegister = () => {
registerRef.value.validate((vaild) => {
if (vaild) {
console.log(123)
}
})
}
</script>
<style scoped>
.login-wrapper {
background-color: #ededed;
display: flex;
width: 100vw;
height: 100vh;
margin: auto;
}
.login-container {
background-color: #fff;
position: relative;
width: 1000px;
height: 600px;
margin: auto;
overflow: hidden;
border-radius: 5px;
box-shadow: 0 0 10px 5px #ddd;
}
.switch-wrapper {
position: absolute;
z-index: 99;
left: 0;
overflow: hidden;
width: 32%;
height: 100%;
transition: transform 1s ease-in-out;
}
.switch-wrapper::after {
content: '';
display: block;
background-image: url('@/assets/login/login-bg.jpg');
background-size: 1000px 550px;
background-position: top left;
width: 100%;
height: 100%;
overflow: hidden;
transition: all 1s ease-in-out;
}
.active .switch-wrapper {
transform: translateX(calc(1000px - 100%));
}
.active .switch-wrapper::after {
background-position: top right;
}
.txt {
width: 100%;
height: 100%;
transition: all 1s ease-in-out;
}
.top-wrapper {
position: absolute;
width: 260px;
height: 168px;
top: 50px;
background-color: rgba(255, 255, 255, 0.7);
padding: 10px;
border-radius: 5px;
}
.btn-wrapper {
position: absolute;
width: 100px;
height: 36px;
color: #fffffe;
background-color: #6689e2;
font-size: 15px;
border-radius: 30px;
cursor: pointer;
flex-wrap: wrap;
overflow: hidden;
}
.outerBox {
position: absolute;
z-index: 3;
left: 32%;
overflow: hidden;
width: 68%;
height: 100%;
transition: all 1s ease-in-out;
}
.container {
width: 100%;
height: 100%;
background-color: #fffffe;
}
.active .outerBox {
transform: translateX(calc(-1000px + 100%));
}
.ld {
width: 200px;
height: 40px;
position: absolute;
right: 16px;
top: 16px;
}
.title {
font-size: 36px;
line-height: 1.5;
text-align: center;
margin-bottom: 30px;
color: #666;
}
.btn-login {
width: 100%;
}
.row {
display: flex;
display: -webkit-flex;
flex-direction: row;
}
.column {
display: flex;
display: -webkit-flex;
flex-direction: column;
}
.aCenter {
align-items: center;
}
.jCenter {
justify-content: center;
}
</style>
效果如下
结合这个页面整理一下常用的Form表单验证和
<script setup lang="ts"><>的写法
vue setup 语法糖总结
设置响应式数据
设置对象或者属性变为响应式的写法有两种:定义为ref(适用于单个属性),定义为reactive(适用于一个对象)。举个例子:假如说一个列表页面如果需要设置加载中,可以定义loading为ref,如果需要提交查询可以将查询条件封装为一个对象,然后定义为reactive,例如下边这些代码
提交Form表单
如果想要提交form表单数据,需要使用reactive先定义一个响应式对象,然后在对应的组件中使用V-model绑定对象。步骤如下
- 定义响应式form表单对象
- 初始化form并将响应式对象的属性使用v-model对应到组件上
Form表单数据验证
setup下基于确定好的规则验证form表单数据步骤可以分为以下几步
- 定义一个响应式数据执行需要验证的表单,我一般使用ref
const loginRef = ref() - 定义规则,如果是只需要验证是否需要输入,只需要定义required为true、message为提示信息、tigger为blur即可。如果需要使用添加自己的验证方法,去除message替换为validator然后指向自己的方法
- 定义form表单使用该规则
- 提交时验证:在提交的方法里使用validate验证
此处因为定义数据是ref,所以需要使用ref.value.validate,在里边判断是否验证通过,然后直接将form提交即可。这样就完成了在setup语法糖里验证表单的功能
结语
上一篇文章立下flag要写一个首页,但是在引入echarts时,使用require引入遇到了一些问题。下篇文章计划使用import按需引入echarts,计划明天出文档。
欢迎关注我的掘金账号:juejin.cn/user/261290…
欢迎star我的git项目:gitee.com/liangminghu…
下期预告:设计一个花里胡哨(不怎么好看)的首页和引入echarts时遇到的坑以及处理方法。