我正在学习 Rails、Vue 和 JS,并且我有一个关于使用 Vue 组件正确处理 Rails 上的提交按钮来验证它的问题。我正在使用 mdbootstrap 作为样式。
我构建了一个表单向导,它使用 vee-validate 来验证字段,在某些表单中我也想执行一些服务器端操作(例如:使用地理编码验证确切地址)。我目前基本上面临三个问题。
- 尽管我添加了一个 v-clock 指令,但每次加载表单向导组件(例如:页面刷新)时,我仍然会看到一点闪烁。
- 我必须解决 Rails 自动数据禁用处理以使其工作,它看起来对我来说不是最佳的,我想知道是否有更好的方法来处理它(我不得不禁用提交事件传播和防止默认并手动禁用/启用,否则来自 Rails UJS 的处理程序将在之后接收它并永久禁用按钮)。
- 尽管该按钮再次启用,但如果验证失败,每次单击它时它都会变亮(可能来自 mdbootstrap 的某些处理程序?)。它仅在我单击浏览器上的刷新按钮后才会发生,并且我注意到每次单击后都会创建以下 div,然后在表单验证期间出现错误,导致按钮变得“更亮”,就像累积的“禁用效果”一样:
有人对如何解决这些问题有想法吗?谢谢!
新的.html.erb:
<div id="stepper">
<div v-cloak>
<transition-group name="fade">
<div class="d-none d-lg-block" key="progress_bar">
<%= render 'forms/progress_bar' %>
</div>
<div id="step1" v-if="step === 1" key="step1">
<%= render 'forms/description' %>
</div>
<div id="step2" v-if="step === 2" key="step2">
<%= render 'forms/address' %>
</div>
</transition-group>
</div>
</div>
_description.html.erb:
<template>
<form
id="description-form"
data-vv-scope="description-form"
novalidate="true"
@submit.prevent="next('description-form', $event)">
<div class="row mb-5">
<div class="col-lg-12 col-md-12">
<div class="container">
<div class="row" id="step-1">
<div class="col-lg-6">
<div class="max-height-80">
<div class="mb-4">
<h4><%= t(:'step1.title') %></h4>
</div>
<div class="form-group">
<label
for="name"
class="control-label">
<%= t(:'step1.label.name') %>
</label>
<input
id="name"
name="name"
type="text"
class="form-control"
placeholder="<%= t(:'step1.input.name') %>"
v-validate="'required'"
v-model="name"
:class="{ 'is-invalid': errors.has('name','description-form') }"
required/>
<div
v-if="errors.has('name','description-form')"
class="invalid-feedback">
<%= t(:'name.required') %>
</div>
</div>
<div class="form-group">
<label
for="description"
class="control-label">
<%= t(:'step1.label.description') %>
</label>
<textarea
id="description"
name="description"
class="form-control"
placeholder="<%= t(:'step1.input.description') %>"
rows="11"
v-validate="'required'"
v-model="description"
:class="{ 'is-invalid': errors.has('description','description-form') }"
required>
</textarea>
<div
v-if="errors.has('description','description-form')"
class="invalid-feedback">
<%= t(:'description.required') %>
</div>
</div>
</div>
<footer class="page-footer white fixed-bottom d-block d-sm-none z-depth-1" id="footer">
<div class="d-flex justify-content-end">
<button class="btn btn-default pull-right" type="submit" data-remote="true" data-disable-with="<%= wait_spinner %>"><%= t(:'btn.next') %></button>
</div>
</footer>
<div class="d-none d-sm-block">
<div class="d-flex justify-content-end mt-2">
<button class="btn btn-default pull-right" type="submit" data-remote="true" data-disable-with="<%= wait_spinner %>"><%= t(:'btn.next') %></button>
</div>
</div>
</div>
<div class="col-lg-2"></div>
<div class="col-lg-4 d-none d-lg-block mt-lg-5">
</div>
</div>
</div>
</div>
</div>
</form>
</template>
stepper.js
var element = document.getElementById("stepper");
if (element != null) {
Vue.use(VeeValidate);
Vue.use(VueResource);
Vue.http.headers.common['X-CSRF-Token'] = document.querySelector('meta[name="csrf-token"]').getAttribute('content');
const stepper = new Vue({
el: element,
data() {
return {
/**
* The step number (starting from 1).
* @type {Integer}
*/
step:1,
name:null,
description:null
}
}
},
methods: {
/**
* Goes back to previous stepp
*/
prev() {
this.step--;
},
/**
* Triggers validation of current step and goes to the
* next step if validation succeeds
* @param {String} scope The step scope used for validation.
* @param {Object} Event that triggered the next step (form submit)
*/
next(scope, event) {
if (event != undefined) {
event.stopImmediatePropagation();
event.preventDefault();
event.stopPropagation();
}
const form = event.currentTarget;
$("button[type=submit]",form).each(function() {
Rails.disableElement(this);
});
this.validateFields(scope, event);
},
validateFields(scope, event) {
this.$validator.validateAll(scope).then(function (valid) {
this.postFieldsValidation(valid, event);
}.bind(this));
},
postFieldsValidation(valid, event) {
if (valid) {
stepper.step++;
}
const form = event.currentTarget;
$("button[type=submit]",form).each(function() {
Rails.enableElement(this);
});
},
handleError(error) {
alert(error)
},
submit() {
}
}
});
}
* 编辑 * 对于#3,当重新启用表单上的元素时,我正在使用一种解决方法来删除按钮内带有 wave-ripple 类的 div。
$("div").remove("button .waves-ripple");
但是,很高兴知道它的根本原因。