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 验证替换验证,但是我的表单部分更改了字段的外观并略有错误,所以这会很混乱
据我了解:
- 我无法设置初始数据值,因为这会覆盖输入值。
- 我可以设置一个道具,但这是不可变的
- 我能找到的任何帮助都建议 'using a computed property which determines its value from the prop',但如果你真的这样做,它不会更新。
这是我目前的情况:
<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'));
经过多次谷歌搜索并找到 Vue.js 论坛后,我准备放弃。
我正在创建一个 Postcode Lookup 组件,在我尝试将它与 Laravel 的表单验证结合使用之前,一切都运行良好 - 特别是当出现错误时,表单会重新填写旧的值。
希望我涵盖了这里的所有内容。我有一个表单输入部分,我使用它生成每个表单输入。它还使用 Laravel 的 old(...)
值(如果存在)。
问题是因为有一个空字符串的默认值(在本例中为邮政编码和地址),这会覆盖邮政编码输入的值属性和地址文本区域的内容。
在人造土地上,理想情况是:
data : function() {
return {
postcode : old('postcode'),
address : old('address'),
addresses : [],
hasResponse : false,
selectedAddress : ''
};
},
这就是我要复制的内容。
我可能可以用 Ajax 验证替换验证,但是我的表单部分更改了字段的外观并略有错误,所以这会很混乱
据我了解:
- 我无法设置初始数据值,因为这会覆盖输入值。
- 我可以设置一个道具,但这是不可变的
- 我能找到的任何帮助都建议 'using a computed property which determines its value from the prop',但如果你真的这样做,它不会更新。
这是我目前的情况:
<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'));