我正在使用Vue.js和Bootstrap设计网站。我有一个要在其上运行自定义验证的表单。直到用户单击“提交”为止,该方法都可以正常工作,这会根据引导文档将application/octet-stream
类添加到表单中。
这时,任何需要输入的字段(无论是否满足我的自定义验证要求)都会被标记为有效,并带有绿色边框和复选标记。我的自定义验证仍在运行,并且正确显示was-validated
。但是,似乎b-form-invalid-feedback
会将具有所需道具的字段标记为有效,而未考虑我的自定义验证,这会导致验证冲突,因为字段具有绿色的复选标记(因为它满足必需的属性),但是仍然是错误消息,因为根据我的自定义验证它尚未生效。
我尝试删除was-validated
样式,但这并不是我想要的效果,因为我确实希望它在每次验证均有效时显示这些样式。希望如果没有,我会提供图片。我还有第二个问题,我有一个日期选择器,即使添加了:valid
也根本不显示b-form-invalid-feedback
。
我的代码
was-validated
<b-form @submit.prevent="addReview" name="review-form" novalidate>
<div class="name">
<label class="sr-only" for="form-input-name">Name</label>
<b-input id="form-input-name" class="form-inputs mb-2 mr-sm-2 mb-sm-0" v-model="name" placeholder="Name" required :state="isStateValid(this.name)"></b-input>
<b-form-invalid-feedback id="form-input-name">
You must enter a name
</b-form-invalid-feedback>
</div>
<div class="date">
<label class="sr-only" for="example-datepicker">Choose a date</label>
<b-form-datepicker id="datepicker" v-model="dateVisited" class="mb-2" required placeholder="Date Visited" :state="isStateValid(this.dateVisited)"></b-form-datepicker>
<b-form-invalid-feedback id="datepicker">
You must enter a valid date
</b-form-invalid-feedback>
</div>
<div class="service">
<label class="sr-only" for="form-input-service">Service Provided</label>
<b-input id="form-input-service" class="form-inputs mb-2" placeholder="Service Provided" v-model="service" required :state="isStateValid(this.service)"></b-input>
<b-form-invalid-feedback id="form-input-service">
You must enter the service provided
</b-form-invalid-feedback>
</div>
<div class="email">
<label class="sr-only" for="inline-form-input-username">Email</label>
<b-input id="inline-form-input-username" class="form-control mb-2 mr-sm-2 mb-sm-0" placeholder="Email" v-model="email" required :state="emailStateValidation"></b-input>
<b-form-invalid-feedback id="inline-form-input-username">
You must enter the part of your email that comes before the '@' symbol
</b-form-invalid-feedback>
</div>
<div class="domain">
<label class="sr-only" for="inline-form-input-domain">Domain</label>
<b-input-group prepend="@" class="mb-2 mr-sm-2 mb-sm-0">
<b-input id="inline-form-input-domain" placeholder="Domain ex: gmail.com" v-model="domain" required :state="domainStateValidation"></b-input>
<b-form-invalid-feedback id="inline-form-input-domain">
You must enter the part of your email that comes after the '@' symbol
</b-form-invalid-feedback>
</b-input-group>
</div>
<div class="description">
<label class="sr-only" for="textarea-rows">Describe Your Experience</label>
<b-form-textarea class="mb-3 mr-sm-2 mb-sm-0" id="textarea-rows" placeholder="Describe Your Experience" rows="4" required v-model="description" :state="isStateValid(this.description)"></b-form-textarea>
<b-form-invalid-feedback id="textarea-rows">
You must enter a description of your experience
</b-form-invalid-feedback>
</div>
<b-button type="submit">Save</b-button>
</b-form>
问题
computed: {
emailStateValidation() {
if (this.email) {
return this.emailIsValid() ? true : false;
}
return null;
},
domainStateValidation() {
if (this.domain) {
return this.domainIsValid() ? true : false;
}
return null;
},
},
methods: {
emailIsValid() {
let regEx = /^(?!.*@)((^[^\.])[a-z0-9\.!#$%&'*+\-\/=?^_`{|}~"]*)*([^\.]$)/;
return regEx.test(this.email);
},
domainIsValid() {
let regEx = /((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
return regEx.test(this.domain);
},
isStateValid(variable) {
if (variable) {
return variable.length > 0 ? true : false;
}
return null;
},
addReview() {
let mainForm = document.getElementsByName("review-form")[0];
mainForm.classList.add("was-validated");
...
未选择日期答案 0 :(得分:1)
根本上,was-validated
不是引导程序本机的,它是浏览器本机的,它也不了解:state
。如果要使用was-validated
,则不能使用自定义验证。如果要使用自定义验证。请参阅建议2。基本上,使用另一个变量来控制是否应应用验证。
来自bootstrap-vue的文档
设置后,在组件上添加
aria-required="true"
属性。所需的验证需要由您的应用程序处理
您需要显式检查验证是否应显示,文档中尚不清楚required
的实际作用,但它不会影响验证。这就解释了为什么该部分不起作用。我个人在提交时设置了一个全局this.showValidations = true
,以便验证实际上在正确的时间运行,而不是在预期的时间(之前和之后)运行。对于您的情况,可以检查要显式添加的was-validated
类。这不是很好,但似乎必须在这里完成。
答案 1 :(得分:1)
简而言之,从您的Vue模板中的novalidate
中删除<form>
。设置novalidate
时,输入将在其整个生命周期内保持其:valid
状态,直到您显式调用setCustomValidity
为止。 Working Sandbox
由于Bootstrap样式也适用于:valid
或:invalid
状态,因此,即使您的自定义验证器确定输入无效,也将同时应用有效样式和无效样式,即:valid
和.is-invalid
,但我想只是这样,:valid
样式优先于当前编写Bootstrap样式表的方式。
使用̶̶n̶o̶v̶a̶l̶i̶d̶a̶t̶e̶
̶当̶y̶o̶u̶'̶r̶e̶实施完整验证解决方案包括自己̶̶r̶e̶q̶u̶i̶r̶e̶d̶
̶̶v̶a̶l̶i̶d̶a̶t̶o̶r̶.̶强>
借助Bootstrap,由于它还将样式应用于输入的:valid
或:invalid
状态,因此最好不要使用novalidate
。
当然,这将使浏览器弹出窗口要求填写某些可能不需要的字段。
建议:在表单上使用validated
属性并将其绑定到表单的状态,并在true
中将其设置为addReview()
,它将自动添加{ {1}}类,您无需直接操作DOM。
编辑:由于删除was-validated
会启用浏览器验证,因此不会在表单上触发novalidate
事件,因此,submit
类不会添加到表单中。这在我的原始答案中提出了一个问题,因为没有was-validated
时不会显示消息和图标。我已经修改了沙箱,以提供针对此问题的解决方案,该解决方案是将was-validated
事件绑定到提交按钮以进行验证逻辑,并使用click
事件来完成成功验证后应该发生的事情。
日期选择器的编辑:日期选择器从未失效的原因是由于submit
方法中的问题,尤其是以下部分:
isStateValid()
由于if(variable) { // "" evaluates to false
// ...
}
的计算结果为false,因此它将始终返回""
。该问题的解决方法是与上述建议结合使用,以维护表单的null
状态。现在,我们不检查validated
,而是检查if(variable)
,如果它是if(this.validated)
,我们只需检查长度并返回true
或true
。>