Задать вопрос
trakhtenberg
@trakhtenberg

Как принудительно вызвать computed свойство в компоненте vue 2?

Доброго времени суток!
Проблема в следующем.
Есть форма, в ней 4 поля (имя, телефон, почта, код).
Для первых 3 - это input, поле кода (тоже input) оформлено компонентом.
Сначала все это проверяется на заполнение, а телефон и почта - еще и на корректность. Все работает отлично. Ввел параметры, нажал кнопку формы "Отправить", проверки прошли - поля с ошибками подсветились красной рамкой и текстом внизу.

А вот дальше, если предыдущий шаг без ошибок (все введено и в правильном формате) значение кода отправляется через axios на серверный API на проверку уже собственно существования кода в базе. API возвращает response (правильный, это проверено). Но вот отрисовка поля после проверки не хочет показывать статус сразу: все показывается только после того, как я кликаю на любое другое поле, а потом снова на поле кода (потеря и получение фокуса, по сути). Разумеется, мне надо, чтобы диагностика была сразу, как и в первой части, без дополнительных кликов.

Буду признателен за идеи.
P.S. Код могу показать, разумеется! Как лучше? Сразу дать ссылку на сервере и под отладчиком смотреть, или как?
https://jsfiddle.net/LouDminsk/42s93nq5/2/ - от HTML оставил только вызов компонента + еще одно поле (для сравнения), JS-часть включена полностью. Но я использую VUE 2.6.14, а в этом инструменте только 2.2.1
  • Вопрос задан
  • 715 просмотров
Подписаться 1 Средний 4 комментария
Решения вопроса 1
Aetae
@Aetae Куратор тега Vue.js
Тлен
Во-первых: тебе намекнули уже в комментах:
computed свойства в vue пересчитываются когда меняются их реактивные зависимости, которые участвовали в предыдущих вычислениях

Т.е. на пальцах: ты обратился в computed к this.value - теперь он смотрит за изменениями this.value. Твоё же computed ни к чему не обращается, оно просто возвращает функцию, её содержимое и вызовы к computed не относятся.

Для понимания:
Вот этот твой код:
computed: {
  validatedClass() {
    return (input) => {
      return {
        'uk-form-success': this.wasValidated && !this.errors[input],
        'uk-form-danger': this.wasValidated && this.errors[input],
      }
    }
  }
},

равносилен:
function someRandomFunction(input) => {
  return {
    'uk-form-success': this.wasValidated && !this.errors[input],
    'uk-form-danger': this.wasValidated && this.errors[input],
  }
}
computed: {
  validatedClass() {
    return someFunction.bind(this);
  }
},

Такой computed будет обновлён только когда Vue пошлёт. В идеале, на самом деле, никогда.

По сути ты просто написал обычный метод, но через одно место.)

Во-вторых: проблема у тебя в другом: this.errors = {}.
Из-за ограниченных возможностей сеттеров, новые ключи, добавленные в объект таким образомthis.errors.email = [] - не реактивны.
Добавлять ключи надо либо черезthis.$set(this.errors, 'email', []) либо, что лучше, заранее:
this.errors = {
  email: '',
  // ...
}


Ну и в третьих: менять что-то в this.$children - очень очень очень плохо. Просто используй props. Такая возможность наличествует только для крайне сложных случаев в компонентах библиотек. Точно не для твоего.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
trakhtenberg
@trakhtenberg Автор вопроса
Aetae хоть это и не решение, но натолкнуло на мысль, как решить :) психанул, переписал все - вместо 251 строки неработающего как надо файла .js получилось 179 строки (до такого же, но работающего функционала). Так что все равно спасибо!
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы