Vue.js 组件结合 Laravel 表单验证(即传递数据的初始值)

Vue.js Component combined with Laravel Form Validation (i.e. passing an initial value for data)

经过多次谷歌搜索并找到 Vue.js 论坛后,我准备放弃。

我正在创建一个 Postcode Lookup 组件,在我尝试将它与 Laravel 的表单验证结合使用之前,一切都运行良好 - 特别是当出现错误时,表单会重新填写旧的值。

希望我涵盖了这里的所有内容。我有一个表单输入部分,我使用它生成每个表单输入。它还使用 Laravel 的 old(...) 值(如果存在)。

问题是因为有一个空字符串的默认值(在本例中为邮政编码和地址),这会覆盖邮政编码输入的值属性和地址文本区域的内容。

在人造土地上,理想情况是:

data : function() {
    return {
        postcode        : old('postcode'),
        address         : old('address'),
        addresses       : [],
        hasResponse     : false,
        selectedAddress : ''
    };
},

这就是我要复制的内容。

我可能可以用 Ajax 验证替换验证,但是我的表单部分更改了字段的外观并略有错误,所以这会很混乱

据我了解:

这是我目前的情况:

<so-postcode-lookup initial-postcode="{{ old('postcode') }}" initial-address="{{ old('address') }}"></so-postcode-lookup>

/**
 * Allow user to select an address from those found in the postcode database
 */
Vue.component('so-postcode-lookup', {
    name     : 'so-postcode-lookup',
    template : '#so-postcode-lookup-template',
    props    : ['initialPostcode', 'initialAddress'],
    data     : function() {
        return {
            postcode        : '',
            address         : '',
            addresses       : [],
            hasResponse     : false,
            selectedAddress : ''
        };
    },
    computed : {
        currentAddress : function() {
            if (this.address !== '') {
                return this.address;
            } else {
                return this.initialAddress;
            }
        },
        currentPostcode : function() {
            if (this.postcode !== '') {
                return this.postcode;
            } else {
                return this.initialPostcode;
            }
        },
        hasAddresses : function() {
            return this.addresses.length;
        },
        isValidPostcode : function() {
            return this.postcode !== '' && this.postcode.length > 4;
        },
        isInvalidPostcode : function() {
            return !this.isValidPostcode;
        }
    },
    methods : {
        fetchAddresses : function() {
            var resource = this.$resource(lang.ajax.apiPath + '/postcode-lookup{/postcode}');
            var $vm      = this;
            var element  = event.currentTarget;

            // Fetch addresses from API
            resource.get({ postcode : this.postcode }).then(function(response) {
                response = response.body;

                if (response.status == 'success') {
                    // Update addresses property, allowing select to be displayed
                    $vm.addresses = response.data;
                } else {
                    $vm.addresses = [];
                }

                this.hasResponse = true;
            });
        },
        setAddress : function() {
            this.address = this.selectedAddress;
        }
    }
});

<template id="so-postcode-lookup-template">
    <div class="row">
        @include('partials.input', [
            'label'                  => trans('register.form.postcode'),
            'sub_type'               => 'postcode',
            'input_id'               => 'postcode',
            'autocorrect'            => false,
            'input_attributes'       => 'v-model="currentPostcode"',
            'suffix_button'          => true,
            'suffix_button_reactive' => trans('register.form.postcode_button_reactive'),
            'suffix_text'            => trans('register.form.postcode_button'),
            'required'               => true,
            'columns'                => 'col-med-50',
            'wrapper'                => 'postcode-wrapper'
        ])

        <div class="col-med-50 form__item" v-show="hasResponse">
            <label for="address-selector" class="form__label" v-show="hasAddresses">{{ trans('forms.select_address') }}</label>
            <select id="address-selector" class="form__select" v-show="hasAddresses" v-model="selectedAddress" @change="setAddress">
                <template v-for="address in addresses">
                    <option :value="address.value">@{{ address.text }}</option>
                </template>
            </select>
            <so-alert type="error" allow-close="false" v-show="!hasAddresses">{{ trans('forms.no_addresses') }}</so-alert>
        </div>

        @include('partials.input', [
            'label'            => trans('register.form.address'),
            'input_id'         => 'address',
            'type'             => 'textarea',
            'input_attributes' => 'v-model="currentAddress"',
            'required'         => true
        ])
    </div>
</template>

如果我尝试这样做,并将输入的模型分别设置为 currentPostcode 和 currentAddress,我似乎得到了一个无限循环。

我想我想多了。

你不能直接绑定到 prop,但你可以使用 prop 设置一个初始值,然后绑定到它,如果你需要双向绑定,这是可行的方法:

Vue.component('my-input', {
  props: {
    'init-postcode': {
      default: ""
    }
  },
  created() {
    // copy postcode to data
    this.postcode = this.initPostcode;
  },
  data() {
    return {
      postcode: ""
    }
  },
  template: '<span><input type="text" v-model="postcode"> {{ postcode }}</span>'
});

然后就这样做:

<div id="app">
  <my-input init-postcode="{{ old('postcode') }}"></my-input>
</div>

这是 fiddle:https://jsfiddle.net/vL5nw95x/

如果您只是想设置初始值,但不需要双向绑定,那么您可以直接引用道具 - 因为您不会应用任何更改 - 使用 v-bind:value :

Vue.component('my-input', {
  props: {
    'init-postcode': {
      default: ""
    }
  },
  template: '<span><input type="text" :value="initPostcode"> {{ postcode }}</span>'
});

和标记:

这是 fiddle:https://jsfiddle.net/pfdgq724/

我正在以一种简单的方式使用 laravel 5.4 控制器直接发送数据

在 Laravel 视图中:

 <input  class="form-control"  id="ciudad" name="ciudad" type="text"  v-model="documento.ciudad"  value="{{ old('ciudad',  isset($documento->ciudad) ? $documento->ciudad : null) }}" >

在 vue.js 2.0

 data: {

    documento: {
      ciudad: $('#ciudad').val(),
    },

},

在Laravel控制器中

  $documento = ReduJornada::where("id_documento",$id)->first();

  return view('documentos.redujornada')->with(compact('documento'));