首页 > 解决方案 > 使用 laravel 和 vuejs 输入期间的动态数据存储

问题描述

我在 vue js 上有一个多步骤表单。我需要在输入期间动态发送请求,在服务器上进行验证并接收响应以显示验证错误。

我的数据:

data() {
    return {
        form: {...this.candidate}, // we get an object with fields already filled *
        errors: new Errors(), // object with validation errors
    }
},

现在对于每个输入,我都有计算属性:

characteristicFuturePlans: {
    get() {
        return this.form.characteristic_future_plans;
    },
    set(value) {
        this.saveField('characteristic_future_plans', value);
    }
},

saveField 方法发送数据:

saveField(field, value) {
    this.form[field] = value; // keep the data in the object relevant
    axios.put(`/api/candidate/${this.candidate.token}`, {[field]: value})
        .then(() => { this.errors.clear(field) })
        .catch((error) => {
            this.errors.record(field, error.response.data.errors[field]);
        });
},

现在,随着输入的每次更改,都会发送一个请求。但是使用这种方法,当我们在字段中快速键入文本时,有时发送的倒数第二个请求会排在最后一个之后。事实证明,如果您快速编写“Johnny”,有时会在带有文本“Johnny”的查询之后出现带有文本“Johnn”的查询,并且错误的值将保存在数据库中。

然后我确保在文本输入终止后 1 秒发送数据。添加 timerId: {} 到 data(){} 然后:

saveField(field, value) {
    if(this.timerId[field]) {
        clearTimeout(this.timerId[field]);
    }
    this.timerId[field] = setTimeout(this.send, 1000, field, value);
},
send(field, value) {
    this.form[field] = value;
    axios.put(`/api/candidate/${this.candidate.token}`, {[field]: value})
        .then(() => { this.errors.clear(field) })
        .catch((error) => {
            this.errors.record(field, error.response.data.errors[field]);
        });
},

但是现在,如果在填写完输入后不到一秒钟,按下按钮进入表单的下一步,页面就会简单地刷新。(进入下一步的按钮会向服务器发送请求,检查是否填写了必填字段)

在文本输入期间如何正确地将数据保存到数据库中?我可以在没有 setTimeout() 的情况下执行此操作吗?如果是这样,我如何确保最后一个请求的数据而不是倒数第二个请求的数据存储在数据库中?我会很高兴任何提示。

更新。 附上一些模板代码。

Step[i].vue 组件的一部分:

<div class="row">
    <div class="form-group col-md-6">
        <element-form  title="Title text" :error="errors.get('characteristic_future_plans')" required isBold>
        <input-input v-model="characteristicFuturePlans" :is-error="errors.has('characteristic_future_plans')"
            :placeholder="'placeholder text'"/>
        </element-form>
    </div>
</div>

输入-输入组件模板:

<input :value="value" :type="type" class="form-control" :class="isErrorClass" 
       :placeholder="placeholder" @input="$emit('input',$event.target.value)">

从页面组件调用表单步骤的组件。Nearby 是用于移动到下一步的按钮组件。

<component :is="currentStep"
           :candidate="candidate"
           // many props
           :global-errors="globalErrors"/>

<next-step :current-step="step" :token="candidate.token"
           @switch-step-event="switchStep" @throw-errors="passErrors"></next-step>

NextStep 组件向服务器发送请求,它正在检查数据库中是否填写了必填字段。如果不是,则抛出验证错误。如果是这样,请转到下一个表单步骤。

标签: laravelvue.jsaxios

解决方案


您可以尝试查看输入值,然后使用_.debounce()underscore.js (src: https://underscorejs.org/#debounce ) 来延迟发出服务器请求的方法调用:

   watch: {
        fieldName: _.debounce(function(value) {
            if(value === ''){
                return;
            }
            this.saveField(this.fieldName, value);
        },
        ...

推荐阅读