【问题标题】:Vue.js Element UI form validation - display errors from backendVue.js Element UI 表单验证 - 显示来自后端的错误
【发布时间】:2020-05-16 02:46:15
【问题描述】:

我正在为我的项目使用 Vue.js 和 Element Ui 库。我有一些规则的基于前端的验证。但我还需要从后端实现显示错误(针对当前字段)。当表单被发送并且后端返回错误时,它看起来像这样:

[
  {"message": "email address is invalid", "path": ["email"]},
  {"message": "example error for password field", "path": ["password"]}
]

其中路径是基于我的表单字段模型的字段名称。

我创建了一些额外的元素来显示来自后端的错误,正如您在我的小提琴中看到的那样。但我想使用 vue element ui 验证。所以后端错误应该以与前端消息相同的方式显示。我不知道该怎么做。

这是我的小提琴:https://jsfiddle.net/ts4Lfxb6/

表单代码如下:

<el-form :model="loginForm" :rules="rules" ref="loginForm" label-position="top">
      <el-form-item label="Email" prop="email">
        <el-input v-model="loginForm.email" :disabled="formProcessing" ref="loginInput"></el-input>
        <p v-if="isErrorForField('email', errors)">{{ getErrorForField('email', errors) }}</p>
      </el-form-item>
      <el-form-item label="Password" prop="password">
        <el-input v-model="loginForm.password" :disabled="formProcessing" type="password"></el-input>
        <p v-if="isErrorForField('password', errors)">{{ getErrorForField('password', errors) }}</p>
      </el-form-item>
      <el-form-item>
        <div class="submit-wrapper">
          <el-button type="primary" @click="submit('loginForm')" :loading="formProcessing">Log in</el-button>
        </div>
      </el-form-item>
    </el-form>

完整的组件在这里:

var Main = {
  data() {
    return {
      loginForm: {
        email: '',
        password: ''
      },
      rules: {
        email: { required: true, message: 'Required', trigger: 'change' },
        password: { required: true, message: 'Required', trigger: 'change' }
      },
      formProcessing: false,
      errors: []
    }
  },
  methods: {
    isErrorForField (field, errors) {
      if (!errors && !errors.length) {
        return false
      }
      let filtered = errors.filter(error => {
        return error.path[0] === field
      })
      if (filtered.length) {
        return filtered
      }
    },
    getErrorForField (field, errors) {
      if (!errors && !errors.length) {
        return false
      }
      let filtered = errors.filter(error => {
        return error.path[0] === field
      })
      if (filtered.length) {
        return filtered[0].message
      }
    },
    supportGlobalErrorMessage () {
      this.errors.forEach(error => {
        if (!error.path.length) {
          this.$message({
            message: error.message,
            type: 'error'
          })
        }
      })
    },
    submit (formName) {
      this.$refs[formName].validate(valid => {
        if (!valid) {
          return false
        }
        this.formProcessing = true
        // send data to backend
        // error response looks like this:
        let errors = [
          {"message": "email address is invalid", "path": ["email"]},
          {"message": "example error for password field", "path": ["password"]}
        ]
        setTimeout(() => {
            this.formProcessing = false
          this.errors = errors
          this.supportGlobalErrorMessage()
        }, 500)
      })
    }
  }
}
var Ctor = Vue.extend(Main)
new Ctor().$mount('#app')

有人可以帮忙吗?

【问题讨论】:

    标签: javascript vue.js element-ui


    【解决方案1】:

    对您的代码进行了以下更改:

    var Main = {
      data() {
        return {
          loginForm: {
            email: '',
            password: ''
          },
          rules: {
            email: {
              required: true,
              //validator: this.customValidator,
              //trigger: 'blur'
            },
            password: {
              required: true,
              //validator: this.customValidator,
              //trigger: 'blur'
            }
          },
          formProcessing: false,
          errors: []
        }
      },
      methods: {
        customValidator(rule, value, callback) {
          console.log(rule)
          if (!value) {
            callback(new Error('The field is required'))
          }
          let errors = [{
              "message": "email address is invalid",
              "path": ["email"]
            },
            {
              "message": "example error for password field",
              "path": ["password"]
            }
          ]
          setTimeout(() => {
            this.errors = errors
    
            if (this.isErrorForField(rule.fullField, this.errors)) {
              callback(new Error(this.getErrorForField(rule.fullField, this.errors)))
            }
            callback()
          }, 500)
        },
        isErrorForField(field, errors) {
          if (!errors && !errors.length) {
            return false
          }
          let filtered = errors.filter(error => {
            return error.path[0] === field
          })
          if (filtered.length) {
            return filtered
          }
        },
        getErrorForField(field, errors) {
          if (!errors && !errors.length) {
            return false
          }
          let filtered = errors.filter(error => {
            return error.path[0] === field
          })
          if (filtered.length) {
            return filtered[0].message
          }
        },
        supportGlobalErrorMessage() {
          this.errors.forEach(error => {
            if (!error.path.length) {
              this.$message({
                message: error.message,
                type: 'error'
              })
            }
          })
        },
        submit(formName) {
          this.$refs[formName].validate(valid => {
            if (!valid) {
              return false
            }
            this.formProcessing = true
            // send data to backend
            // error response looks like this:
            let errors = [{
                "message": "email address is invalid",
                "path": ["email"]
              },
              {
                "message": "example error for password field",
                "path": ["password"]
              }
            ]
            setTimeout(() => {
              this.errors = errors
              this.formProcessing = false
              this.supportGlobalErrorMessage()
            }, 500)
          })
        }
      }
    }
    var Ctor = Vue.extend(Main)
    new Ctor().$mount('#app')
    @import url("//unpkg.com/element-ui@2.0.5/lib/theme-chalk/index.css");
    <script src="//unpkg.com/vue/dist/vue.js"></script>
    <script src="//unpkg.com/element-ui@2.0.5/lib/index.js"></script>
    <div id="app">
      <el-form :model="loginForm" :rules="rules" ref="loginForm" label-position="top">
        <el-form-item label="Email" prop="email" :error="getErrorForField('email', errors)">
          <el-input v-model="loginForm.email" :disabled="formProcessing" ref="loginInput"></el-input>
          <!-- <p v-if="isErrorForField('email', errors)">{{ getErrorForField('email', errors) }}</p> -->
        </el-form-item>
        <el-form-item label="Password" prop="password" :error="getErrorForField('password', errors)">
          <el-input v-model="loginForm.password" :disabled="formProcessing" type="password"></el-input>
          <!-- <p v-if="isErrorForField('password', errors)">{{ getErrorForField('password', errors) }}</p> -->
        </el-form-item>
        <el-form-item>
          <div class="submit-wrapper">
            <el-button type="primary" @click="submit('loginForm')" :loading="formProcessing">Log in</el-button>
          </div>
        </el-form-item>
      </el-form>
    </div>

    rules属性中的validator属性可以设置自定义验证规则,接收三个参数(规则、值、回调)。

    rule:源描述符中与正在验证的字段名称对应的验证规则。它总是被分配一个带有被验证字段名称的字段属性。

    value:正在验证的源对象属性的值。

    callback:验证完成后调用的回调函数。它期望传递一个错误实例数组来指示验证失败。如果校验是同步的,可以直接返回false或者Error或者Error数组。

    所以,你可以从后端获取数据并进行处理,然后通过callback显示错误信息。

    【讨论】:

    • 这几乎就是我想要的。还有一个问题,当字段中没有值时,如何显示“该字段为必填项”消息?如果有一些价值和形式被发送应该像你的例子一样工作。当然,如果后端返回错误。谢谢。
    • @Marek 已编辑 :) 检查一下~
    • 谢谢,但我仍然无法弄清楚如何仅在提交表单时显示后端错误,您能帮忙吗?
    • @Marek 好的。设置error 属性,该字段将验证错误并立即显示此消息
    猜你喜欢
    • 2019-12-15
    • 2020-08-07
    • 2017-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-26
    • 1970-01-01
    相关资源
    最近更新 更多