Необходимость связывания выбранных битов внешних данных в $ data - PullRequest
0 голосов
/ 05 мая 2019

Я фанат Vue , который иногда пытаются использовать.Во всяком случае, есть кое-что, что я всегда находил не очень удобным: реактивность лежит в пределах $data.Ну, не всегда, поскольку Vue может отслеживать внешние данные, как в вычисляемых свойствах, в шаблонах ... Но я нашел этот способ неудобным и не всегда последовательным (см. Другой вопрос по этому поводу, здесь Реакция на переменные, не связанные с данными,Вычисляется и т. Д. ).Поэтому мое решение сейчас - использовать $data в качестве основного источника реактивности и прекратить пытаться найти другие пути.

Однако, реактивность в $data создает для меня проблему в том, что часто встречается для меня: многиекуски данных здесь и там в других импортированных объектах.Это имеет еще больший смысл, так как я считаю Vue концом View, а не бизнес-логикой.Эти импортированные объекты иногда бывают сложными, и в компонентах Vue я не нашел способа черпать кусочки информации и попросить Vue связать их.Единственный способ состоял в том, чтобы объявить целые объекты в разделе $data, что делает отслеживание очень тяжелым: нагрузки сеттеров / получателей, когда в простом компоненте, например, будет достаточно только одного.

Поэтому я разработал классназывается ' Reactor ', роль экземпляров которого заключается в установке геттеров / сеттеров на любые кусочки данных моего желания в сложном объекте (или более чем в одном).Эти экземпляры импортируются в компоненты Vue, а затем $watchers экземпляров Reactor имеют свойства, которые могут содержать столько функций, сколько мне нужно, которые вызываются, когда фрагменты данных изменяются через Reactor.Для простоты по умолчанию используется то же имя свойства, что и для данных, к которым оно привязано.Это именно те функции, которые будут обновлять $data при изменении внешних данных.

class Reactor {
  constructor() {
    this.$watchers = {};
  }
  addProperty(originalObject, keyString, aliasKeyString) {
    if(aliasKeyString === undefined) {
      aliasKeyString = keyString;
    }
    if(this[aliasKeyString] !== undefined || originalObject[keyString] === undefined) {
      const errorMessage = `Reactor: cannot add property '${aliasKeyString}'!`;
      console.error(errorMessage);
      throw errorMessage;
    }
    this.$watchers[aliasKeyString] = [];
    Object.defineProperty(this, aliasKeyString, {
      set(newValue) {
        const oldValue = originalObject[keyString];
        originalObject[keyString] = newValue;
        this.$watchers[aliasKeyString].forEach((f) => {
          if(typeof f === "function") {
            f(newValue, oldValue, aliasKeyString);
          }
        });
      },
      get() {
        return originalObject[keyString];
      },
   });
  }
}

Пример можно увидеть в коде ручки здесь: https://codepen.io/Djee/pen/gyVZMG Так что это своего рода инвертированный ' 'Vue, которая позволяет обновлять $data при внешних условиях.

Этот шаблон также помог мне разрешить случай, который до этого был довольно сложным: иметь двойное связывание на входе с фильтром, между которымиустановит вход и его внешнее значение только при событии @change.Это можно увидеть в том же коде, указанном выше.

Я был немного удивлен, что ничего не нашел, взяв это во внимание в самой Vue .Я что-то упустил очевидное?Это в основном цель этого несколько длинного вступления.У меня не было времени проверить, будет ли Vuex решить эту проблему.

Спасибо за любые комментарии.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...