1

我正在学习 Rails、Vue 和 JS,并且我有一个关于使用 Vue 组件正确处理 Rails 上的提交按钮来验证它的问题。我正在使用 mdbootstrap 作为样式。

我构建了一个表单向导,它使用 vee-validate 来验证字段,在某些表单中我也想执行一些服务器端操作(例如:使用地理编码验证确切地址)。我目前基本上面临三个问题。

  1. 尽管我添加了一个 v-clock 指令,但每次加载表单向导组件(例如:页面刷新)时,我仍然会看到一点闪烁。
  2. 我必须解决 Rails 自动数据禁用处理以使其工作,它看起来对我来说不是最佳的,我想知道是否有更好的方法来处理它(我不得不禁用提交事件传播和防止默认并手动禁用/启用,否则来自 Rails UJS 的处理程序将在之后接收它并永久禁用按钮)。
  3. 尽管该按钮再次启用,但如果验证失败,每次单击它时它都会变亮(可能来自 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");

但是,很高兴知道它的根本原因。

4

0 回答 0