如何在VueJs元素中应用个别错误消息?

时间:2018-06-09 07:22:41

标签: vue.js element

我在应用程序中有一个表单(http://element.eleme.io/#/en-US/component/form),我在那里进行服务器端验证。但我还没有说明如何为特定输入添加错误消息。

4 个答案:

答案 0 :(得分:0)

我正在使用 Laravel ,我通常会这样做,我在Laravel控制器中的验证

AuthController.savePassword = function(req, res) {
  var potentialUser = { where: { username: req.body.username } };
  models.user.findOne(potentialUser).then(function(user, err) {
    if (err) {

    } else {
      if (req.body.password === null || req.body.password === '') {
        res.status(404).json({ message: 'You need to provide a new password' });
      } else {
        user.password = req.body.password; // Save user's new password to the user object
        user.resettoken = false; // Clear user's resettoken
        user.save((err) => {
          if (err) {
            res.status(404).json({ message: 'Save error' });
          }
        }).then(() => {
          res.status(201).json({ message: 'Password changed' });
        });
      }
    }
  });
}

如果出现错误,我的vue.js代码

    return Validator::make($data, [
        'email' => 'required|email',
        'password' => 'required|min:6',
    ]);

完整的vue组件

if(error.response.status == 400){
    let errors = error.response.data.errors;
    for(let i in errors){
        document.querySelector("div[for='"+i+"']").innerHTML = errors[i][0];
    }
}else if(error.response.status == 401){
    console.log(error.response);
    let errors = error.response.data;
    document.querySelector("div[for='password']").innerHTML = errors;
}

相关的laravel控制器方法

const Login = { 
template: `
    <div class="container">
      <div class="row row-body"> 
        <div class="col-12 col-md-6 offset-md-3">
          <div class="row">
            <div class="col-12 col-md-12 text-center">
              <h1>Login</h1>
            </div>
          </div>
          <div class="row">
            <div class="col-12 col-md-12">
              <form method="POST" action="">

                <div class="row pt-3 pb-3">
                  <div class="col-12 col-md-10 offset-md-1 form-group">
                    <input class="form-control form-rounded" placeholder="Email*" v-model="email">
                    <div for="email" class="text-danger"></div>
                  </div>
                </div>
                <div class="row pb-3">
                  <div class="col-12 col-md-10 offset-md-1 form-group">
                    <input class="form-control" placeholder="Password*" v-model="password" type="password">
                    <div for="password" class="text-danger"></div>
                  </div>
                </div>
                <div class="row pt-3">
                  <div class="col-12 col-md-12 form-group text-center">
                    <button @click="login" class="btn as-btn-outline as-btn-dark mx-2 my-2 my-sm-0 big-btn" type="button">LOGIN</button>
                  </div>
                </div>
              </form>
            </div>
          </div>
        </div>
      </div>
    </div>
`,
data(){
    return {
        email: '',
        password: ''
    }
},
mounted(){
    /**/
},
methods:{
        login: function(){
            var formdata = {};
            formdata.email = this.email;
            formdata.password = this.password;
            axios
                  .post('http://far.test/api/login',formdata)
                  .then(response => {
                    console.log(response.data);
                    if(response.data.token !== undefined){
                        this.$parent.is_auth = true;
                        sessionStorage.setItem('asset_token', response.data.token);
                        router.push({ path: '/home' });
                    }
                  })
                  .catch(error => {
                    if(error.response.status == 400){
                        let errors = error.response.data.errors;
                        for(let i in errors){
                            document.querySelector("div[for='"+i+"']").innerHTML = errors[i][0];
                        }
                    }else if(error.response.status == 401){
                        console.log(error.response);
                        let errors = error.response.data;
                        document.querySelector("div[for='password']").innerHTML = errors;
                    }

                  })
                  .finally(() => console.log('finally')/*this.loading = false*/);

        },
    }
}

答案 1 :(得分:0)

每个el-form-item需要prop属性才能使前端验证生效。他们还需要绑定错误属性。为了简单起见,我使每个字段名称都与字段名称相同,如下所示:

<el-form-item label="Email" prop="email" :error="errors.email">
    <el-input v-model="form.email" type="email"></el-input>
</el-form-item>

然后,在提交表单时,我运行前端规则的验证器(使用Element的规则)。之后,我使用axios发布到服务器(Laravel)。我遍历所有错误,并更新errors对象中的值。每当提交表单时,我都会清除错误(如果您不清除它们,错误将不会在连续的表单提交中显示。)

data() {

    let passwordsMatch = (rule, value, callback) => {
        if ( value != this.form.password )
            return callback(new Error('Passwords do not match'));

        return callback();
    };

    let form = {
        first_name: '',
        last_name: '',
        email: '',
        phone: '',
        password: '',
        password_confirmation: '',
    };

    // copy blank values, not reference
    let errors = {...form};
    let blankErrors = {...form};

    return {

        form,

        errors,

        blankErrors,

        rules: {
            first_name: [
                { required: true, message: 'First Name is required', trigger: 'blur' },
            ],
            last_name: [
                { required: true, message: 'Last Name is required', trigger: 'blur' },
            ],
            email: [
                { required: true, message: 'Email is required', trigger: 'blur' },
                { type: 'email', message: 'Must be an email', trigger: 'blur' },
            ],
            phone: [
                { required: true, message: 'Cell Phone is required', trigger: 'blur' },
                // TODO: finish phone validation
                //{ type: 'number', message: 'Must be a phone number', trigger: 'blur' },
            ],
            password: [
                { required: true, message: 'Password is required', trigger: 'blur' },
            ],
            password_confirmation: [
                { required: true, message: 'Password is required', trigger: 'blur' },
                { validator: passwordsMatch, trigger: 'blur' },
            ],
        },
    }
},

methods: {

    createAccount() {

        this.clearErrors();


        let passed = this.runValidator();

        if (! passed) return;


        axios.post(`/register`, this.form)
            .then(response => {

                EventBus.$emit('user-form-completed', this.form);

                return;

            })
            .catch(error => {

                const errors = error.response.data.errors;

                for (let index in errors) {

                    let error = errors[index][0];

                    this.errors[index] = error;
                }
            });
    },


    clearErrors() {
        this.errors = {...this.blankErrors};
    },


    runValidator() {

        let passed = false;

        this.$refs.form.validate((valid) => {
            if (valid) passed = true;
        });

        return passed;
    },
},

答案 2 :(得分:0)

我想出了基于Laracast project的Laravel解决方案。这种方法的优点是Error类是可重用的。

在您的component.vue中,

  • 使用errors.get('field')绑定单个输入错误,例如:error =“ errors.get('email')”
  • 导入错误类(请参见下面的代码段)
  • 将错误对象添加到vue数据
  • 发出axios请求并记录响应数据

<template>
  <el-form  label-position="top"
            label-width="100px"
            :model="loginForm"
            :rules="rules"
            @submit.prevent="validateForm"
            ref="loginForm"
            status-icon validate-on-rule-change>

    <el-form-item label="email" prop="email" :error="errors.get('email')">
      <el-input   v-model="loginForm.email" placeholder="Enter your email"></el-input>
    </el-form-item>

    <el-form-item label="password" prop="password" :error="errors.get('password')">
      <el-input   v-model="loginForm.password" placeholder="Enter your password"></el-input>
    </el-form-item>

    <!-- Note about get() method in :error="errors.get('password')" see errors js -->

  </el-form>
</template>

<script>
  import { Errors } from './../templates/errors.js';
  export default {

    // Data
    data() {
      return {
        loginForm: {
          email: '',
          password: '',
        },

        // This is where we manage laravel errors
        errors: new Errors(),

        // Local validation disabled
        rules: {
          email: [
            { required: false, message: 'Please enter your email', trigger: 'blur' },
            // required set to false to for the sake of testing with laravel
          ],
          password: [
            { required: false, message: 'Please enter your password', trigger: 'blur' },
            // required set to false to for the sake of testing with laravel
          ],
        }
      };
    },

    // Methods
    methods: {

        // Validate form data
        submitForm(loginForm) {

// Clear Laravel errors before submitting form
this.errors.clear()

          this.$refs[loginForm].validate((valid) => {
            if (valid && ! this.errors.any()) {
              console.log('Data is validated. Submitting' + this.loginForm);
              this.login()
this.$refs[loginForm].validate()

            } else {
              console.log('Cannot submit, Invalid data');
              return false;
            }
          });
        },

        // post data
        login(){
          axios.post('/login'.login, this.loginForm).then( response => {
            // Data submitted successifully
          })
          .catch(error => {
            // There was an error like
            this.errors.record(error.response.data.errors)
            // Note: see errors.js for record method
          });
        }

    }
  }
</script>

然后导入errors.js(信用Laracast project

export class Errors {
    /**
     * Create a new Errors instance.
     */
    constructor() {
        this.errors = {};
    }


    /**
     * Determine if an errors exists for the given field.
     *
     * @param {string} field
     */
    has(field) {
        return this.errors.hasOwnProperty(field);
    }


    /**
     * Determine if we have any errors.
     */
    any() {
        return Object.keys(this.errors).length > 0;
    }


    /**
     * Retrieve the error message for a field.
     *
     * @param {string} field
     */
    get(field) {
        if (this.errors[field]) {
            return this.errors[field][0];
        }
    }

    /**
     * Retrieve flash message if any
     *
     * @param {string} field
     */
    getFlash(field) {
        if (this.errors[field]) {
            return this.errors[field];
        }
    }


    /**
     * Record the new errors.
     *
     * @param {object} errors
     */
    record(errors) {
        this.errors = errors;
    }


    /**
     * Clear one or all error fields.
     *
     * @param {string|null} field
     */
    clear(field) {
        if (field) {
            if (this.has(field)) {
                delete this.errors[field];
            }

            return;
        }

        this.errors = {};
    }
}

答案 3 :(得分:0)

添加具有任何名称的裁判并执行以下操作:

In js do this
this.$refs.formData.errorBucket=[]
<v-text-field                                                                  
  ref="formData"
  :rules="[rules.required, rules.max]">
</v-text-field>