使用的是Vite + TypeScipt方法+ Bootstrap V5
Vue3.2 Composition API Setup语法 实现 V-Model 输入表单内容,响应式,并且双向绑定数据
废话不多说,直接上全部的源码。
src\components\ValidateInput.vue(子组件)
<template>
<div class="validate-input-container pb-3">
<input
type="text"
class="form-control"
:class="{ 'is-invalid': InputRef.error }"
:value="InputRef.val"
@input="updateValue"
@blur="validateInput"
/>
<span v-if="InputRef.error" class="invalid-feedback">{{
InputRef.message
}}</span>
</div>
</template>
<script setup lang="ts">
import { EmailRuleProps, IEmail } from "../types/userProps";
import { PropType, toRefs, reactive, ref, watch } from "vue";
import { tabBarProps } from "element-plus";
const emailReg = /^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/;
type RuleProps = EmailRuleProps[];
const props = defineProps({
rules: {
type: Array as PropType<RuleProps>,
},
modelValue: {
type: String,
},
});
const InputRef: IEmail = reactive({
val: props.modelValue || "",
error: false,
message: "",
});
const InputRefs = toRefs(InputRef);
const validateInput = () => {
if (props.rules) {
const allPassed = props.rules.every((rule) => {
let passed = true; //临时变量
InputRef.message = rule.message; //把错误消息重赋值
switch (rule.type) {
case "required":
passed = InputRef.val.trim() !== "";
break;
case "email":
passed = emailReg.test(InputRef.val);
break;
default:
break;
}
return passed;
});
InputRef.error = !allPassed;
}
};
const emit = defineEmits(["update:modelValue"]);
const updateValue = (e: Event) => {
// 定义输入的值
const targetValue = (e.target as HTMLInputElement).value;
//赋值
InputRef.val = targetValue;
//发送事件
emit("update:modelValue", targetValue);
};
</script>
<style scoped></style>
src\components\LoginForm.vue(父组件)
<template>
<div class="root">
<div class="container-fluid">
<div class="row align-items-center">
<div class="col"></div>
<div class="col">
<h2 class="text-center fw-bold">后台登陆</h2>
<form>
<div class="mb-3">
<label class="form-label">邮箱地址:</label>
<ValidateInput :rules="emailRules" v-model="testInputValue" ></ValidateInput>
{{ testInputValue }}
</div>
<div class="mb-3">
<label for="exampleInputPassword1" class="form-label"
>登陆密码:</label
>
<input
type="password"
class="form-control"
id="exampleInputPassword1"
/>
</div>
<div class="mb-3 form-check">
<input
type="checkbox"
class="form-check-input"
id="exampleCheck1"
/>
<label class="form-check-label" for="exampleCheck1">记住我</label>
</div>
<div class="d-grid gap-2">
<button type="submit" class="btn btn-primary">提交</button>
</div>
</form>
</div>
<div class="col"></div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { EmailRuleProps } from "../types/userProps";
import ValidateInput from "./ValidateInput.vue";
import {ref} from 'vue'
const testInputValue = ref('adf@qq.com')
const emailRules: EmailRuleProps[] = [
{ type: "required", message: "邮箱地址不能为空" },
{ type: "email", message: "邮箱格式不正确" },
];
</script>
<style scoped>
.row {
height: 500px;
}
/* .container-fluid{
background-color: #087360;
} */
</style>
src\types\userProps.ts
export interface IUserProps {
isLogin: boolean;
userName?: string;
userID?: number;
}
export interface IEmail {
val: string;
error: boolean;
message: string;
}
export interface EmailRuleProps {
type: "required" | "email";
message: string;
}
WX:临武IT哥