【问题标题】:Can't get error handing in vue.js 1.0 and Laravel 5.1 to work无法在 vue.js 1.0 和 Laravel 5.1 中进行错误处理
【发布时间】:2016-02-10 17:51:59
【问题描述】:

我正在构建一个应用程序,它使用 vue.js 和 Laravel 5 将数据持久保存到数据库中。至此,可以成功保存数据了。

我的问题

当使用 Laravel 的“开箱即用”授权用户验证失败时,我无法显示错误。我不断收到错误:

[Vue warn]: Error when evaluating expression "form.errors.length > 0"

(在我下面的代码中指的是errors.js

拼凑起来

那么这应该如何工作...用户在注册页面中输入他们的详细信息,Vue(使用 vue-resource)向“开箱即用”的 Laravel AuthController@postRegister 方法发出 AJAX 请求。出错时,Laravel 会很好地吐出我们都期望的 JSON 错误消息。现在理论上,我的subscription.js 文件中的sendRegistration 方法应该检测Laravel 吐出的错误(我已经用console.log 测试过它并且它有效)并将它们传递给errors.js 组件以显示<spark-errors> 标签中的错误。为了做到这一点,它在我的<head> 标签中使用了setErrorsOnForm: 函数。但是它没有按预期工作,我无法确定原因。

我的代码

我的代码包含一个注册页面:

<!DOCTYPE html>
<html lang="en">
<head>
<!-- Laravel Spark Globals -->
    <script>
        window.Spark = {
            // Laravel CSRF Token
            csrfToken: '{{ csrf_token() }}',

            // Flatten errors and set them on the given form
            setErrorsOnForm: function (form, errors) {
                if (typeof errors === 'object') {
                    form.errors = _.flatten(_.toArray(errors));
                } else {
                    form.errors.push('Something went wrong. Please try again.');
                }
            }
        }
    </script>
</head>
<body>
    <div id="spark-app">
<spark-subscription-register-screen inline-template>
<div class="panel panel-default">
    <div class="panel-heading">Your Information</div>
    <div class="panel-body">
        <spark-errors form="@'{'{ registerForm '}'}"></spark-errors>

        <form class="form-horizontal" role="form" id="subscription-basics-form">

            <div class="form-group">
                <label class="col-md-4 control-label">Your Name</label>
                <div class="col-md-6">
                    <input type="text" class="form-control spark-first-field" name="name" v-model="registerForm.name">
                </div>
            </div>

            <div class="form-group">
                <label class="col-md-4 control-label">E-Mail Address</label>
                <div class="col-md-6">
                    <input type="email" class="form-control" name="email" v-model="registerForm.email">
                </div>
            </div>

            <div class="form-group">
                <label class="col-md-4 control-label">Password</label>
                <div class="col-md-6">
                    <input type="password" class="form-control" name="password" v-model="registerForm.password">
                </div>
            </div>

            <div class="form-group">
                <label class="col-md-4 control-label">Confirm Password</label>
                <div class="col-md-6">
                    <input type="password" class="form-control" name="password_confirmation" v-model="registerForm.password_confirmation">
                </div>
            </div>

            <div v-if="freePlanIsSelected">
                <div class="form-group">
                    <div class="col-sm-6 col-sm-offset-4">
                        <div class="checkbox">
                            <label>
                                <input type="checkbox" v-model="registerForm.terms"> I Accept The <a href="/terms" target="_blank">Terms Of Service</a>
                            </label>
                        </div>
                    </div>
                </div>

                <div class="form-group">
                    <div class="col-sm-6 col-sm-offset-4">
                        <button type="submit" class="btn btn-primary" v-on:click="register" :disabled="registerForm.registering">
                            <span v-if="registerForm.registering">
                                <i class="fa fa-btn fa-spinner fa-spin"></i> Registering
                            </span>

                            <span v-if=" ! registerForm.registering">
                                <i class="fa fa-btn fa-check-circle"></i> Register
                            </span>
                        </button>
                    </div>
                </div>
            </div>
        </form>
    </div>
</div>
</spark-subscription-register-screen inline-template>
</div>
</body>
</html>

从 vue.js 的角度来看,有一个 subscription.js 文件:

Vue.component('spark-subscription-register-screen', {

    /*
     * Initial state of the component's data.
     */
    data: function () {
        return {
            registerForm: {
                nhs_org: '', team_name: '', name: '', email: '', password: '', password_confirmation: '',
                plan: '', terms: false, coupon: null, invitation: null,
                stripe_token: null, errors: [], registering: false
            },
        };
    },

    methods: {
        /*
         * Initialize the registration process.
         */
        register: function(e) {
            var self = this;

            e.preventDefault();

            this.registerForm.errors = [];
            this.registerForm.registering = true;

            return this.sendRegistration();
        },

        /*
         * After obtaining the Stripe token, send the registration to Spark.
         */
        sendRegistration: function() {
            this.$http.post('/register', this.registerForm)
                .success(function(response) {
                    window.location = '/';
                })
                .error(function(errors) {
                    this.registerForm.registering = false;
                    Spark.setErrorsOnForm(this.registerForm, errors);
                });
        },
    }

});

还有一个errors.js Vue 组件:

/*
 * Common Error Display Component.
 */
Vue.component('spark-errors', {
    props: ['form'],

    template: "<div><div class='alert alert-danger' v-if='form.errors.length > 0'>\
                <strong>Whoops!</strong> There were some problems with your input.<br><br>\
                <ul>\
                    <li v-for='error in form.errors'>\
                        {{ error }}\
                    </li>\
                </ul>\
            </div></div>"
});

现在将所有这些拼凑在一起的 Vue 文件(以正确的顺序):

app.js:

require('./core/dependencies');

if ($('#spark-app').length > 0) {
    new Vue(require('./core/spark.js'));
}

核心/dependencies.js:

/*
 * Load Vue & Vue-Resource.
 *
 */
if (window.Vue === undefined) window.Vue = require('vue');

require('vue-resource');
Vue.http.headers.common['X-CSRF-TOKEN'] = Spark.csrfToken;

/*
 * Load Underscore.js, used for map / reduce on arrays.
 */
if (window._ === undefined) window._ = require('underscore');

/*
 * Load jQuery and Bootstrap jQuery, used for front-end interaction.
 */
if (window.$ === undefined || window.jQuery === undefined) window.$ = window.jQuery = require('jquery');
require('bootstrap-sass/assets/javascripts/bootstrap');

核心/spark.js:

/*
 * Load the Spark components.
 */
require('./components');

/**
 * Export the Spark application.
 */
module.exports = {
    el: '#spark-app',

    /*
     * Bootstrap the application. Load the initial data.
     */
    ready: function () {
        $(function() {
            $('.spark-first-field').filter(':visible:first').focus();
        });
    }
}

和核心/components.js:

require('./../auth/registration/subscription');
require('./../common/errors');

【问题讨论】:

  • 您应该仔细检查 form 属性是否在您的 @{{$data|json}} 组件模板中正确填充了 'spark-errors'

标签: javascript laravel vue.js


【解决方案1】:

我遇到了同样的问题,我没有使用 spark 的开箱即用错误,而是定义了自己的组件:

<template>
    <div v-if="errors">
        <div class="alert alert-danger" v-if="formattedErrors.length > 0">
            <strong>Whoops!</strong> There were some problems with your input.<br><br>
            <ul>
                <li v-for="error in formattedErrors">
                    {{ error }}
                </li>
            </ul>
        </div>
    </div>
</template>

<script>
    export default {
        props: ['errors'],
        computed: {
            formattedErrors() {
                return this.format(this.errors);
            }
        },
        methods: {
            format(errors) {
                if (typeof errors === 'undefined') {
                    return [];
                }
                if (typeof errors === 'object') {
                    return _.flatten(_.toArray(errors));
                }
            }
        }
    }
</script>

然后你在你的 html 中绑定:

<form-errors :errors="registerForm.errors"></form-errors>

这是有道理的,因为您的组件现在只需要关于错误的信息,而不需要关于 registerForm 的其他信息。

希望这会有所帮助。

【讨论】:

    猜你喜欢
    • 2019-08-10
    • 2015-06-12
    • 2022-06-23
    • 1970-01-01
    • 2023-03-22
    • 2016-03-21
    • 2015-11-18
    • 2016-02-17
    • 1970-01-01
    相关资源
    最近更新 更多