У меня есть свойство во vuex, в которое записывается ширина страницы по событию resize. Так же есть свойство с набором брейкпоинтов для каждого раздела сайта (объект с ключами, соответствующими разделам сайта, каждому ключу соответствует массив брейкпоинтов). На основе этих свойств геттер выдаёт объект с текущими брейкпоинтом для каждого раздела сайта. Ну и дальше уже на основе этого геттера вычисляется множество других свойств в разных компонентах.
Я внезапно понял, что реактивность во vue работает не всегда так как мне бы этого хотелось. Получается, что когда геттер вычисляет объект с текущими брейкпоинтами он каждый раз отдаёт новый объект и другие свойства, которые зависят от этого геттера тоже начинают пересчитываться по новой даже если по сути все значения в объекте который отдал геттер остались прежними. В результате при изменение размера окна сайт нефигово так подлагивает.
Я вижу решение этой проблемы в том, чтобы не использовать геттер, а вместо этого самому следить за изменениями разрешения экрана и перезаписывать объект с текущими брейкпоинтами только тогда когда он действительно изменился. И в целом видимо этот же принцип нужно применять для любых вычисляемых свойств, которые отдают объекты или массивы, на основе которых может происходить большое количество вычислений. Но это ведь разрушает все преимущества от красоты и декларативности геттеров и вычисляемых свойств. Может быть можно как-то дать понять vuex'у, что результат вычисления геттера не изменился и можно использовать предыдущий результат?
Вы брикпойнты по ресайзу что ли пересчитываете? Это мрак.
Попробуйте использовать 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');
Сергей delphinpro, хм, спасибо, честно говоря не знал, что можно на них события вешать. Спасибо)
Но вопрос в его общем виде всё равно остаётся открытым. Если у нас есть геттер, который возвращает объект/массив, то как можно возвращать тот же самый объект, что и раньше, если по факту ничего не изменилось?
LordGuard, Смотрите. У вас будет свойство во вьюксе
state.breakpoint = '';
Пусть оно будет принимать значения 'xs', 'sm', 'lg'
Вы сделаете три медиазапроса max-width:300, min301 and max700, min701
По срабатыванию matchMedia эти значения будут меняться в стейте.
Любое вычисляемое свойство, которое будет опираться на store.state.breakpoint, будет пересчитано только когда это свойство изменится, т.е. при перешагивании через заданную точку. В остальное время вычислялки, за счет кэширования, будут возвращать неизменные значения.
Сергей delphinpro, я понял то как работать с медиазапросами, но у меня другой вопрос. К моему примеру пускай он уже и не применим, но всё равно актуален.
Сергей delphinpro, если геттер возвращает объект или массив, то это вызывает пересчёт свойств, зависящих от этого геттера даже в том случае если данные в объекте, который вернул геттер никак не изменились. Могу ли я каким-то образом возвращать результат прошлого вычисления геттера, если данные на самом деле не изменились?