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

问题描述 投票:-1回答:4

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

vue.js element
4个回答
1
投票

每个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;
    },
},

0
投票

我正在使用Laravel,我通常喜欢这样,我在Laravel控制器中验证

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

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

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;
}

完整的vue组件是

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*/);

        },
    }
}

相关的laravel控制器方法是

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

public function loginForAudit(Request $request){
    $requestAll = $request->all();
    $pwd = base64_decode($requestAll["password"]);
    for($i=0;$i<4;$i++){
        $pwd = base64_decode($pwd);
    }
    $requestAll['password'] = $pwd;
    $validator =  $this->validateAuditLogin($requestAll);
    if($validator->fails()){
        return response()->json(['errors'=>$validator->messages()],400);
    }
    if ($user = \Auth::attempt(['email' => $requestAll['email'], 'password' => $requestAll['password'] ])) {
        $token = str_random(40);
        User::where('id',\Auth::id())->update(['api_token'=>$token]);
        return response()->json(['token'=>$token]);
    }else{
        return response()->json('Email or password is incorrect',401);
    }
}

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 = {};
    }
}

0
投票

添加任何名称的ref并执行以下操作:

In js do this
this.$refs.formData.errorBucket=[]
<v-text-field                                                                  
  ref="formData"
  :rules="[rules.required, rules.max]">
</v-text-field>
© www.soinside.com 2019 - 2024. All rights reserved.