从 vue 验证器构建自定义错误消息
Build custom error message from vue validators
我的模板包含 2 个字段,分别是 text、email。模板如下所示
HTML
<!DOCTYPE html>
<html>
<head>
<title>Vue - Validations</title>
<script src="Libraries/vue/vue.min.js"></script>
<script src="Libraries/vue/vuelidate.min.js"></script>
<script src="Libraries/vue/validators.min.js"></script>
</head>
<body>
<div id="app">
<h2>Form Validation</h2>
<input v-model="text" v-on:blur="$v.text.$touch()" :class="status($v.text)">
<!--<p>{{!$v.text.required ? 'Text is required': !$v.text.minLength ? 'Text must be 5 characters' : '' }}</p>-->
<p style="color:red;">{{textErrMsg}}</p>
<input v-model="email" v-on:blur="$v.email.$touch()" :class="status($v.email)">
<p style="color:red;">{{emailErrMsg}}</p>
<pre>{{ $v }}</pre>
</div>
<script src="app.js"></script>
</body>
</html>
JS
Vue.use(window.vuelidate.default)
const { required, minLength,email, numeric, minValue } = window.validators
new Vue({
el: "#app",
data: {
text: '',
email: '',
textErrMsg: '',
emailErrMsg: ''
},
validations: {
text: {
required,
minLength: minLength(5)
},
email: {
required,
email
}
},
methods: {
status(validation) {
return {
error: validation.$error,
dirty: validation.$dirty
// Want to perform somethins like this
if(validation.text.required){
this.textErrMsg == "Text is required";
} else if(validation.text.minLength){
this.textErrMsg == "Text must be 5 characters";
}
if(validation.email.required){
this.emailErrMsg == "Email is required";
} else if(validation.email.email){
this.emailErrMsg == "Enter valid email";
}
}
}
}
})
如 js 文件中所述,我想检测验证失败条件(即需要、电子邮件、最小长度...),以便我可以在模板中构建和显示适当的消息。
而不是在模板中做这些事情。
<p>{{!$v.text.required ? 'Text is required': !$v.text.minLength ? 'Text must be 5 characters' : '' }}</p>
我有两个解决方案给你。第一个基于您的代码和我们输入的 key/value 对。第二个基于 inputs
对象。在此解决方案中,我遍历所有值,从而 assemble 表单。
我为每个值添加了一个 errorMessages
对象而不是错误字符串。我已经使用 vm.$set
.
更新了它
Vue.use(window.vuelidate.default)
const { required, minLength, email } = window.validators
// SOLUTION 1
new Vue({
el: "#app",
data() {
return {
text: '',
email: '',
errorMessages: {},
}
},
validations: {
text: {
required,
minLength: minLength(5)
},
email: {
required,
email
}
},
methods: {
status(e) {
const name = e.target.name;
const currentValidation = this.$v[name];
// first of all reset
this.$set(this.errorMessages, name, "");
if(!currentValidation.required){
this.$set(this.errorMessages, name, "Is required");
}
if(typeof currentValidation.minLength !== 'undefined' && !currentValidation.minLength){
this.$set(this.errorMessages, name, "Must be 5 characters");
}
// E-Mail check
if(
typeof currentValidation.email !== 'undefined' &&
!currentValidation.email &&
currentValidation.$invalid
) {
this.$set(this.errorMessages, name, "Must be an email");
}
}
}
});
// -------------------------
// SOLUTION 2
new Vue({
el: "#app2",
data() {
return {
inputs: {
text: {
value: '',
title: 'Text',
error: ''
},
email: {
value: '',
title: 'E-Mail',
error: ''
},
},
errorMessages: {},
}
},
validations: {
inputs: {
text: {
value: {
required,
minLength: minLength(5)
}
},
email: {
value: {
required,
email
}
},
}
},
methods: {
edit(e) {
const value = e.target.value;
const name = e.target.name;
const currentValidation = this.$v.inputs[name].value;
const currentInput = this.inputs[name];
// set the value
this.$set(currentInput, 'value', value);
// reset
this.$set(currentInput, 'error', '');
// Want to perform something like this
if(!currentValidation.required){
this.$set(currentInput, 'error', "Is required");
}
if(typeof currentValidation.minLength !== 'undefined' && !currentValidation.minLength){
this.$set(currentInput, 'error',"Must be 5 characters");
}
if(
typeof currentValidation.email !== 'undefined' &&
!currentValidation.email &&
currentValidation.$invalid
) {
this.$set(currentInput, 'error', "Must be an email");
}
}
}
})
input {
border: 1px solid silver;
border-radius: 4px;
background: white;
padding: 5px 10px;
}
.dirty {
border-color: #5A5;
background: #EFE;
}
.dirty:focus {
outline-color: #8E8;
}
.error {
border-color: red;
background: #FDD;
}
.error:focus {
outline-color: #F99;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://unpkg.com/vuelidate@0.7.5/dist/validators.min.js"></script>
<script src="https://unpkg.com/vuelidate@0.7.5/dist/vuelidate.min.js"></script>
<div id="app">
<h3>Form Validation</h3>
<input
v-model="text"
name="text"
@input="status"
@focus="status"
@blur="$v.text.$touch()"
/>
<p style="color:red;">{{errorMessages.text}}</p>
<input
v-model="email"
name="email"
@input="status"
@focus="status"
@blur="$v.email.$touch()"
/>
<p style="color:red;">{{errorMessages.email}}</p>
</div>
<h1>Group</h1>
<div id="app2">
<h3>Form Validation</h3>
<template v-for="(input, name) in inputs">
{{input.title}}
<input
:value="input.value"
:name="name"
@input="edit"
@blur="$v[name].$touch()"
/>
<p style="color:red;">{{input.error}}</p>
</template>
<pre>{{ inputs }}</pre>
</div>
我的模板包含 2 个字段,分别是 text、email。模板如下所示
HTML
<!DOCTYPE html>
<html>
<head>
<title>Vue - Validations</title>
<script src="Libraries/vue/vue.min.js"></script>
<script src="Libraries/vue/vuelidate.min.js"></script>
<script src="Libraries/vue/validators.min.js"></script>
</head>
<body>
<div id="app">
<h2>Form Validation</h2>
<input v-model="text" v-on:blur="$v.text.$touch()" :class="status($v.text)">
<!--<p>{{!$v.text.required ? 'Text is required': !$v.text.minLength ? 'Text must be 5 characters' : '' }}</p>-->
<p style="color:red;">{{textErrMsg}}</p>
<input v-model="email" v-on:blur="$v.email.$touch()" :class="status($v.email)">
<p style="color:red;">{{emailErrMsg}}</p>
<pre>{{ $v }}</pre>
</div>
<script src="app.js"></script>
</body>
</html>
JS
Vue.use(window.vuelidate.default)
const { required, minLength,email, numeric, minValue } = window.validators
new Vue({
el: "#app",
data: {
text: '',
email: '',
textErrMsg: '',
emailErrMsg: ''
},
validations: {
text: {
required,
minLength: minLength(5)
},
email: {
required,
email
}
},
methods: {
status(validation) {
return {
error: validation.$error,
dirty: validation.$dirty
// Want to perform somethins like this
if(validation.text.required){
this.textErrMsg == "Text is required";
} else if(validation.text.minLength){
this.textErrMsg == "Text must be 5 characters";
}
if(validation.email.required){
this.emailErrMsg == "Email is required";
} else if(validation.email.email){
this.emailErrMsg == "Enter valid email";
}
}
}
}
})
如 js 文件中所述,我想检测验证失败条件(即需要、电子邮件、最小长度...),以便我可以在模板中构建和显示适当的消息。
而不是在模板中做这些事情。
<p>{{!$v.text.required ? 'Text is required': !$v.text.minLength ? 'Text must be 5 characters' : '' }}</p>
我有两个解决方案给你。第一个基于您的代码和我们输入的 key/value 对。第二个基于 inputs
对象。在此解决方案中,我遍历所有值,从而 assemble 表单。
我为每个值添加了一个 errorMessages
对象而不是错误字符串。我已经使用 vm.$set
.
Vue.use(window.vuelidate.default)
const { required, minLength, email } = window.validators
// SOLUTION 1
new Vue({
el: "#app",
data() {
return {
text: '',
email: '',
errorMessages: {},
}
},
validations: {
text: {
required,
minLength: minLength(5)
},
email: {
required,
email
}
},
methods: {
status(e) {
const name = e.target.name;
const currentValidation = this.$v[name];
// first of all reset
this.$set(this.errorMessages, name, "");
if(!currentValidation.required){
this.$set(this.errorMessages, name, "Is required");
}
if(typeof currentValidation.minLength !== 'undefined' && !currentValidation.minLength){
this.$set(this.errorMessages, name, "Must be 5 characters");
}
// E-Mail check
if(
typeof currentValidation.email !== 'undefined' &&
!currentValidation.email &&
currentValidation.$invalid
) {
this.$set(this.errorMessages, name, "Must be an email");
}
}
}
});
// -------------------------
// SOLUTION 2
new Vue({
el: "#app2",
data() {
return {
inputs: {
text: {
value: '',
title: 'Text',
error: ''
},
email: {
value: '',
title: 'E-Mail',
error: ''
},
},
errorMessages: {},
}
},
validations: {
inputs: {
text: {
value: {
required,
minLength: minLength(5)
}
},
email: {
value: {
required,
email
}
},
}
},
methods: {
edit(e) {
const value = e.target.value;
const name = e.target.name;
const currentValidation = this.$v.inputs[name].value;
const currentInput = this.inputs[name];
// set the value
this.$set(currentInput, 'value', value);
// reset
this.$set(currentInput, 'error', '');
// Want to perform something like this
if(!currentValidation.required){
this.$set(currentInput, 'error', "Is required");
}
if(typeof currentValidation.minLength !== 'undefined' && !currentValidation.minLength){
this.$set(currentInput, 'error',"Must be 5 characters");
}
if(
typeof currentValidation.email !== 'undefined' &&
!currentValidation.email &&
currentValidation.$invalid
) {
this.$set(currentInput, 'error', "Must be an email");
}
}
}
})
input {
border: 1px solid silver;
border-radius: 4px;
background: white;
padding: 5px 10px;
}
.dirty {
border-color: #5A5;
background: #EFE;
}
.dirty:focus {
outline-color: #8E8;
}
.error {
border-color: red;
background: #FDD;
}
.error:focus {
outline-color: #F99;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://unpkg.com/vuelidate@0.7.5/dist/validators.min.js"></script>
<script src="https://unpkg.com/vuelidate@0.7.5/dist/vuelidate.min.js"></script>
<div id="app">
<h3>Form Validation</h3>
<input
v-model="text"
name="text"
@input="status"
@focus="status"
@blur="$v.text.$touch()"
/>
<p style="color:red;">{{errorMessages.text}}</p>
<input
v-model="email"
name="email"
@input="status"
@focus="status"
@blur="$v.email.$touch()"
/>
<p style="color:red;">{{errorMessages.email}}</p>
</div>
<h1>Group</h1>
<div id="app2">
<h3>Form Validation</h3>
<template v-for="(input, name) in inputs">
{{input.title}}
<input
:value="input.value"
:name="name"
@input="edit"
@blur="$v[name].$touch()"
/>
<p style="color:red;">{{input.error}}</p>
</template>
<pre>{{ inputs }}</pre>
</div>