javascript - Vue.js Element UI 表单验证 - 显示来自后端的错误

标签 javascript vue.js element-ui

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

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

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

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

这是我的 fiddle :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')

有人可以帮忙吗?

最佳答案

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

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/<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="41242d242c242f356c342801736f716f74" rel="noreferrer noopener nofollow">[email protected]</a>/lib/theme-chalk/index.css");
<script src="//unpkg.com/vue/dist/vue.js"></script>
<script src="//unpkg.com/<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="b0d5dcd5ddd5dec49dc5d9f0829e809e85" rel="noreferrer noopener nofollow">[email protected]</a>/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>

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

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

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

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

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

关于javascript - Vue.js Element UI 表单验证 - 显示来自后端的错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59986817/

相关文章:

javascript - 获取传单中 WMS 的最小缩放级别

vue.js - vee-validate 验证一个不存在的字段

vuejs2 - VueJs + 元素 UI : How to set default value with photo el-select?

css - "Unexpected character ' "导入主题时

vue.js - Vuetify 连接 v-select 的项目文本中的两个字段

webpack - 使用 CDN 的 Vue ElementUI Webpack 外部

javascript - 如何在 Javascript 中为某些标签添加样式(字体大小)

JavaScript:无法从函数正确返回数组

javascript - 计算百分比时,如何防止超过 99% 到 100%

javascript - Vue.js 从另一个组件调用方法