Я фанат 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 решить эту проблему.
Спасибо за любые комментарии.