我有模式窗口的vuejs组件。当用户在我想要的字段中填写所有数据时:
现在我对第 2、4 和 5 点有问题。超时不起作用,模式窗口立即关闭。来自 php 脚本的响应数据在 ROOT Vue 实例中不可用。我只能在组件内部看到服务器响应,但我不知道如何将其传递给 ROOT。
视图\布局.刀片.php
<div v-if="FreeZamerSent" class="alert alert-dismissible fade show" :class="class" role="alert">
@{{ message }}
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<freezamermodal v-if="showFreeZamerModal" @close="showFreeZamerModal = false" @sent="onFreeZamerSent(response)"></freezamermodal>
App\Http\Controllers\MainController.php
public function freezamer(Request $request) {
request()->validate([
'customer_name' => 'required',
'customer_email' => 'required|email',
'customer_phone' => 'required'
]);
Mail::to( env('MAIL_TO_ADDRESS') )->send(new FreeZamer());
return [
'message' => 'Ваша заявка отправлена! В ближайшее время мы свяжемся с вами.',
'alertclass' => 'alert-success',
];
}
资源\js\组件\Free Z amer Modal. vue
<template>
<div class="modal is-active" id="FreezamerModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title" id="myModalLabel">Заказать бесплатный замер</h4>
<button type="button" class="close" data-dismiss="modal" aria-label="Close" @click="$emit('close')">
<span aria-hidden="true">×</span>
</button>
</div>
<form method="POST" action="/freezamer" @submit.prevent="onSubmit">
<input type="hidden" name="_token" :value="csrf">
<div class="modal-body">
<input type="hidden" class="form-control" name="formname" :value="formname">
<input type="hidden" class="form-control" name="currentUrl" :value="currentUrl">
<div class="error" v-if="!$v.customer_name.required">Введите имя</div>
<div class="error" v-if="!$v.customer_name.minLength">Имя должно содержать минимум {{$v.customer_name.$params.minLength.min}} буквы.</div>
<div class="error" v-if="!$v.customer_name.cyrillic">Имя должно состоять только из русских букв</div>
<input type="text" class="form-control" name="customer_name" placeholder="Ваше имя" :class="{ 'form-control--error': $v.customer_name.$error }" v-model.trim="$v.customer_name.$model">
<div class="error" v-if="!$v.customer_email.required">Введите email</div>
<div class="error" v-if="!$v.customer_email.email">Введите существующий email</div>
<input type="text" class="form-control" name="customer_email" placeholder="Ваш e-mail" :class="{ 'form-control--error': $v.customer_email.$error }" v-model.trim="$v.customer_email.$model">
<div class="error" v-if="!$v.customer_phone.required">Введите номер телефона</div>
<div class="error" v-if="!$v.customer_phone.minLength">Телефон должен содержать 11 цифр.</div>
<input type="tel" class="form-control" name="customer_phone" placeholder="Ваш телефон" :class="{ 'form-control--error': $v.customer_phone.$error }" v-model.trim="$v.customer_phone.$model" v-mask="'+# (###) ###-##-##'">
</div>
<div class="modal-footer">
<button class="button button_fill" type="submit" :disabled="$v.$invalid">
<svg v-if="!success"><use xlink:href="#plan"></use></svg>
<i class="fa fa-spinner fa-spin" v-if="success"></i>
<span>Бесплатный замер</span>
</button>
</div>
</form>
</div>
</div>
</div>
</template>
<script>
import { alpha, email, helpers, maxLength, minLength, numeric, required } from 'vuelidate/lib/validators';
import {mask} from 'vue-the-mask';
export const cyrillic = helpers.regex('cyrillic', /^[А-Яа-яёЁ\s]+$/);
export default {
name: "FreeZamerModal",
data: function () {
return {
currentUrl: window.location.pathname,
csrf: document.querySelector('meta[name="csrf-token"]').getAttribute('content'),
formname: 'freezamer',
customer_name: '',
customer_email: '',
customer_phone: '',
success: false,
errors: []
}
},
directives: {mask},
methods: {
onSubmit () {
axios.post('/freezamer', this.$data)
.then(this.onSuccess)
.catch(error => this.errors = error.response.data);
},
onSuccess (response) {
this.success = true;
setTimeout(5000);
this.$emit('sent', response);
},
},
mounted() {
console.log('Freezamer component mounted.')
},
validations: {
customer_name: {
required,
cyrillic,
minLength: minLength(3)
},
customer_email: {
required,
email
},
customer_phone: {
required,
minLength: minLength(18),
maxLength: maxLength(18)
}
}
}
</script>
资源\js\app. js
Vue.component('freezamermodal', require('./components/FreeZamerModal.vue').default);
const app = new Vue({
el: '#app',
data: {
showFreeZamerModal: false,
FreeZamerSent: false,
message: '',
alertclass : '',
},
methods: {
onFreeZamerSent (response) {
this.showFreeZamerModal = false,
this.FreeZamerSent = true,
this.message = this.response.message,
this.alertclass = this.response.alertclass
},
},
});
相反,我在控制台中有错误
[Vue warn]: Property or method "response" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property.
[Vue warn]: Error in v-on handler: "TypeError: Cannot read property 'message' of undefined"
found in
---> <FreeZamerModal> at resources/js/components/FreeZamerModal.vue
<Root>
我一步一步地使用vue-devtools发现了问题。以下代码this.$emit('发送',响应)
将大响应对象传递给ROOT实例并访问response.data工作解决方案如下。唯一的缺点是我无法理解为什么setTimeout不工作。动作this.$emit('发送',响应)
立即触发,而不是在5秒后。5秒后,我在控制台中看到错误。如果删除超时,一切正常。
资源\js\组件\Free Z amer Modal. vue
onSuccess (response) {
this.success = true;
setTimeout(this.$emit('sent', response), 5000);
},
资源\js\app. js
data: {
showFreeZamerModal: false,
FreeZamerSent: false,
message: '',
alertclass: ''
},
methods: {
onFreeZamerSent (response) {
this.showFreeZamerModal = false,
this.FreeZamerSent = true,
this.message = response.data.message,
this.alertclass = response.data.alertclass
},
blade. php
<freezamermodal v-if="showFreeZamerModal" @close="showFreeZamerModal = false" @sent="onFreeZamerSent"></freezamermodal>
控制台错误,5秒钟后出现
VM27172:1 Uncaught SyntaxError: Unexpected identifier
setTimeout (async)
onSuccess @ FreeZamerModal.vue?0b2e:81
Promise.then (async)
onSubmit @ FreeZamerModal.vue?0b2e:75
submit @ FreeZamerModal.vue?b9fb:63
invokeWithErrorHandling @ vue.common.dev.js?4650:1859
invoker @ vue.common.dev.js?4650:2184
original._wrapper @ vue.common.dev.js?4650:7543