У меня есть простой компонент кнопки для отправки форм, и он должен давать небольшую обратную связь при нажатии на него: показать счетчик и отключить кнопку во время отправки формы, а затем также отключить его, если с сервера возвращаются какие-либо ошибки. до тех пор, пока ошибки не будут устранены (ошибки устранены путем изменения ввода полей, в которых они есть).
Вот шаблон компонента:
<template>
<button type="submit" :disabled="disabled">
<loading-spinner v-if="submitting"></loading-spinner>
<slot>Submit</slot>
</button>
</template>
<script>
export default {
props: {
form: {
type: Object,
required: true
}
},
created() {
// Globally available event handler which listens for events
// emitted by Form object - it works fine
Event.$on('submitting', () => this.submitting = true);
Event.$on('submitted', () => this.submitting = false);
},
data() {
return {
submitting: false,
}
},
computed: {
// Here is the problem: this.form.errors.any() doesn't get updated in the
// computed prop even when errors are cleared. This same method, however,
// returns correct result when called directly via a test button
disabled() {
return this.submitting || this.form.errors.any()
},
// doesn't get updated either - apparently
// errors() {
// return this.form.errors.any()
// }
},
}
</script>
Кнопке передается объект Form
, поэтому он также может иметь доступ к объекту Errors
, у которого есть несколько удобных методов для управления ошибками. Объект Form
, который передается в качестве опоры, является реактивным внутри компонента submit-button
, и его поля обновляются в Vue Devtools по мере ввода в форму (в родительском компоненте), но вычисляемая опора (disabled
или errors
), которая полагается на нее, не получать обновления.
Когда я отправляю форму с неверными данными, я получаю ошибки, поэтому form.errors.any()
возвращает true. Однако, как только ошибка возвращается в первый раз, кнопка становится неактивной и вот так зависает (form.errors.any()
продолжает возвращать истину, даже если это не так).
Я знаю, что вычисленные реквизиты кэшируются, но по определению они должны обновляться при обновлении их зависимости (в этом случае вычисляемое свойство disabled
должно обновляться, потому что обновляется this.form.errors.any()
). Однако кажется, что компонент кнопки отправки игнорирует обновление this.form.errors.any()
в своем вычисляемом свойстве (он продолжает возвращать истину при наличии ошибок и никогда не обновляется). То же самое происходит, если я создаю такое же вычисляемое свойство для родительского компонента.
Дополнительная информация
Когда я вручную проверяю его значение (например, с помощью кнопки, вызывающей form.errors.any()
), он каждый раз записывает правильное значение в консоль, но не обновляется в моем вычисляемом свойстве.
Метод any()
на объекте Errors
- здесь ничего особенного
any() {
return Object.keys(this.errors).length > 0;
}
И объект Form, и объект Errors работают нормально: их методы возвращают нормальные значения при прямом вызове (например, посредством нажатия кнопки) из любого компонента, и они отправляют события, как ожидалось, они просто не реагируют на вычисленную опору.
Временное решение
Решением для меня было использование метода вместо вычисляемого свойства, но это слишком многословно, и я в основном хотел бы знать, почему в этом случае я не могу использовать более элегантное вычисляемое свойство?
<template>
<button type="submit" :disabled="submitting || anyErrors()">
<loading-spinner v-if="submitting"></loading-spinner>
<slot>Submit</slot>
</button>
</template>
<script>
export default {
...
methods: {
anyErrors() {
return this.form.errors.any()
}
}
}
</script>
this.errors
- это пустой объект при установке (конструктор), и к нему можно получить доступ / заполнить / очистить с помощью методов (получить / зарегистрировать / очистить и уже упоминалось). - person tal3nce   schedule 10.08.2020