Как избежать сверхреактивности vuex?

У меня есть свойство во vuex, в которое записывается ширина страницы по событию resize. Так же есть свойство с набором брейкпоинтов для каждого раздела сайта (объект с ключами, соответствующими разделам сайта, каждому ключу соответствует массив брейкпоинтов). На основе этих свойств геттер выдаёт объект с текущими брейкпоинтом для каждого раздела сайта. Ну и дальше уже на основе этого геттера вычисляется множество других свойств в разных компонентах.

Я внезапно понял, что реактивность во vue работает не всегда так как мне бы этого хотелось. Получается, что когда геттер вычисляет объект с текущими брейкпоинтами он каждый раз отдаёт новый объект и другие свойства, которые зависят от этого геттера тоже начинают пересчитываться по новой даже если по сути все значения в объекте который отдал геттер остались прежними. В результате при изменение размера окна сайт нефигово так подлагивает.

Я вижу решение этой проблемы в том, чтобы не использовать геттер, а вместо этого самому следить за изменениями разрешения экрана и перезаписывать объект с текущими брейкпоинтами только тогда когда он действительно изменился. И в целом видимо этот же принцип нужно применять для любых вычисляемых свойств, которые отдают объекты или массивы, на основе которых может происходить большое количество вычислений. Но это ведь разрушает все преимущества от красоты и декларативности геттеров и вычисляемых свойств. Может быть можно как-то дать понять vuex'у, что результат вычисления геттера не изменился и можно использовать предыдущий результат?
  • Вопрос задан
  • 272 просмотра
Решения вопроса 1
delphinpro
@delphinpro Куратор тега JavaScript
frontend developer
Вы брикпойнты по ресайзу что ли пересчитываете? Это мрак.
Попробуйте использовать matchMedia
Такие брикопойнты отлично уживаются с реактивностью. Проверено.

На примере одного пойнта (в App.mounted()):

const mqDesktop = window.matchMedia('(min-width: 992px)');
const mqMobile  = window.matchMedia('(max-width: 991px)');
mqDesktop.addListener(e => { if (e.matches) this.setBreakpoint('desktop');});
mqMobile.addListener(e => { if (e.matches) this.setBreakpoint('mobile'); });
if (mqDesktop.matches) this.setBreakpoint('desktop');
if (mqMobile.matches) this.setBreakpoint('mobile');


Здесь this.setBreakpoint() — это мутация вьюкса.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

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

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