Vue. js Проверка формы пользовательского интерфейса элемента - отображать ошибки из бэкэнда - PullRequest
0 голосов
/ 30 января 2020

Я использую Vue. js и библиотеки Element Ui для моего проекта. У меня есть проверка на основе интерфейса с некоторыми правилами. Но мне также нужно реализовать ошибки отображения (для текущего поля) из бэкэнда. Когда форма отправляется и сервер возвращает ошибку, она выглядит следующим образом:

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

где путь - это имя поля, основанное на моей модели поля формы.

Я создал дополнительный элемент, который отображает ошибку из бэкэнд, как вы можете видеть в моей скрипке. Но я хотел бы использовать vue элемент 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')

Может кто-нибудь помочь?

1 Ответ

0 голосов
/ 30 января 2020

Внесены следующие изменения в ваш код:

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>

Свойство validator в атрибуте rules может устанавливать пользовательское правило проверки, которое получает три параметра (rule, value, callback).

rule: Правило проверки в дескрипторе источника, которое соответствует проверяемому имени поля. Всегда присваивается свойство поля с именем проверяемого поля.

value: значение проверяемого свойства исходного объекта.

callback: функция обратного вызова для вызывать после завершения проверки. Ожидается, что будет передан массив экземпляров Error, чтобы указать сбой проверки. Если проверка является синхронной, вы можете напрямую вернуть ложный или массив ошибок или ошибок.

Таким образом, вы можете получить данные из серверной части и обработать их, а затем отобразить сообщение об ошибке через callback.

...