vue3+element-plus表单验证之登录
2021-07-12 14:14 镌刻成诗 阅读(2082) 评论(0) 收藏 举报vue3+element-plus表单验证之登录
上代码
<template>
<div class="container">
<div class="sign-in">
<!-- 登录 -->
<el-form
class="form login-form clear-fix"
ref="loginFormRef"
:model="loginForm"
:rules="loginRules"
>
<el-form-item label="邮箱" prop="email">
<el-input v-model="loginForm.email" type="text" placeholder="请输入邮箱地址" ></el-input>
</el-form-item>
<el-form-item label="密码" prop="pass">
<el-input v-model="loginForm.pass" type="password" placeholder="请输入密码"></el-input>
</el-form-item>
<el-form-item>
<el-row gutter="10px">
<el-col :span="12">
<el-button
type="primary"
class="form-btn submit-btn"
@click="submitForm"
v-if="!successMode"
>
提交
</el-button>
<el-button
type="success"
v-else
class="form-btn"
>
登录成功
</el-button>
</el-col>
<el-col :span="12">
<el-button
class="form-btn reset-btn"
@click="resetForm()"
>
重置
</el-button>
</el-col>
</el-row>
</el-form-item>
<!-- 找回密码 -->
<div class="tiparea">
<p>
忘记密码?
<el-link type="primary">找回密码</el-link>
</p>
</div>
</el-form>
</div>
<div class="sign-up"></div>
</div>
</template>
<script lang="ts">
import { ref, defineComponent, reactive, unref } from 'vue'
import { useRouter } from 'vue-router'
// 对密码和邮箱进行类型限制
interface loginData {
email: string;
pass: string;
}
export default defineComponent({
setup () {
const loginForm = ref<loginData>({
email: '',
pass: ''
})
const router = useRouter()
const loginFormRef = ref()
// 自定义验证规则
const validatePass = (rule, value, callback) => {
// 密码只能由大小写英文字母或数字开头,且由大小写英文字母_.组成
const reg = /^[A-Za-z0-9][A-Za-z0-9_.]{5,14}$/
console.log('reg', value.match(reg))
if (!value.match(reg)) {
callback(new Error('密码由字母或数字开头,且只能为字母,数字,下划线及(.)'))
} else {
callback()
}
}
// 定义校验规则
const loginRules = reactive({
email: [
{ required: true, message: '邮箱不能为空', trigger: 'blur' },
{ type: 'email', message: '邮箱格式不正确', trigger: 'blur' }
],
pass: [
{ required: true, message: '密码不能为空', trigger: 'blur' },
{ min: 6, max: 15, message: '密码位数只能在6~15之间', trigger: 'blur' },
{ validator: validatePass, trigger: 'blur' }
]
})
// 是否登录成功
const successMode = ref<boolean>(false)
// 重置表单
const resetForm = () => {
// 笨办法这么写:
// loginForm.value.email = ''
// loginForm.value.pass = ''
// 明眼人这么写:
const form = unref(loginFormRef)
form.resetFields()
}
// 路由跳转
function goto () {
router.push('/')
}
// 表单提交
const submitForm = async () => {
const form = unref(loginFormRef)
if (!form) {
return
}
try {
await form.validate()
successMode.value = true
// 路由跳转
goto()
} catch (err) {
console.log(err)
}
}
return {
loginFormRef,
loginForm,
loginRules,
resetForm,
submitForm,
successMode,
goto
}
}
})
</script>
<style lang="scss" scoped>
.container {
width: 100%;
height: 100%;
overflow: hidden;
}
.form {
width: 360px;
padding: 20px;
border-radius: 10px;
}
.tiparea {
float: right;
a {
color: blue;
&:hover {
color: red;
cursor: pointer;
}
}
}
.form {
border: 1px solid #ddd;
}
.clear-fix::after {
display: table;
content: "";
overflow: hidden;
clear: both;
}
.login-form {
box-shadow: 5px 5px 5px 5px darken(#145885, 0.1);
}
.form-btn {
width: 48%;
}
.reset-btn {
float: right;
}
.sign-in {
background: url('../assets/login.jpg') no-repeat;
background-size: cover;
width: 100%;
height: 100%;
position: relative;
}
.el-form {
position: absolute;
right: 200px;
top: 200px;
background-color: #fff;
}
</style>
描述
诸君皆明白,setup是拿不到this的。但是官网的案例中是由用到this的,官网没在setup中写。
比如:自定义表单验证官网是这样的:
var validatePass = (rule, value, callback) => {
if (value === '') {
callback(new Error('请输入密码'));
} else {
if (this.ruleForm.checkPass !== '') {
this.$refs.ruleForm.validateField('checkPass');
}
callback();
}
}
再比如表单提交和重置官网再methods里面这样写的
methods: {
submitForm(formName) {
this.$refs[formName].validate((valid) => {
if (valid) {
alert('submit!');
} else {
console.log('error submit!!');
return false;
}
});
},
resetForm(formName) {
this.$refs[formName].resetFields();
}
}
}
他们都用到了this.refs
那么setup中没有this怎么实现呢?
有人如下面这般做的,用这种方式获取组件的实例,但是也有人认为setup中取消this获取实例就是要杜绝使用者获取实例,原因是在某些情况下,编码会变得很复杂,但是有人偏偏这么干,究竟该提倡了还是该反对?我觉得既然vue这么设计,那么使用者应该尽量遵循某些设计理念。
import {getCurrentInstance} from 'vue'
const instance = getCurrentInstance()
看看form中的属性
如同官网一样,我这里也给了form三个必要的属性
<el-form
class="form login-form clear-fix"
ref="loginFormRef"
:model="loginForm"
:rules="loginRules"
>
...
</el-form>
只不过官网的ref是通过this来获取表单元素的的,在setup中我们可以换种方式获取,比如:
在setup中创建一个ref对象
const loginFormRef = ref()
在return中返回
return { loginFormRef }
如何使用:比如重置表单数据
// 重置表单
const resetForm = () => {
// 笨办法这么写:
// loginForm.value.email = ''
// loginForm.value.pass = ''
// 明眼人这么写:
const form = unref(loginFormRef)
form.resetFields()
}
官网是这么做的:
当然这里的formName传的是'loginFormRef'
resetForm(formName) {
this.$refs[formName].resetFields();
}
那么我们如何用正确的姿势优雅地进行表单提交呢?
// 表单提交
const submitForm = async () => {
const form = unref(loginFormRef)
if (!form) {
return
}
try {
await form.validate()
successMode.value = true
// 路由跳转
goto()
} catch (err) {
console.log(err)
}
}
表单提交后如何路由跳转?
首先要引入:
import { useRouter } from 'vue-router'
人后在setup下
const router = useRouter()
然后要在setup中定义一个路由跳转的函数
// 路由跳转
const goto = () => {
router.push('/')
}
你还需要在setup的return中返回这个函数
return { goto }
- 而且貌似只能这么做,只能在setup下,不能再setup下的方法中
- 比如在提交的方法中才定义const router = useRouter()
- 我试过行不通哈
浙公网安备 33010602011771号