использовании shallowRef я вообще никакие изменения не смогу отследить
Зачем же его придумали тогда?
const products = shallowRef(new Map());
products.value.set('someKey', someArray);
// Триггерим изменение
triggerRef(products);
// или
products.value = products.value;
Map создается вместе со store и более не меняется, а списки то как раз будут меняться - при пагинации, смене фильтров на странице, и тому подобного
Меняться будет только весь список целиком, а не ключи каждого товара, а вы c ref реактивность вешаете на каждый ключ каждого товара, хотя с бэка вообще может прилететь гораздо больше ключей, чем на фронте надо. В итоге память на хранение таких данных увеличивается в разы.
Тут получается, что вы пользователю в разы по сравнению с shallowRef увеличиваете нагрузку на процессор и память, т.к. каждому ключу каждого элемента списка создается прокси, чтобы отслеживать изменения, хотя список-то по сути скорее всего никогда и не изменится.
Ок, я понял вашу логику. Процитирую ваш ответ здесь же другому пользователю:
> Внутри стора нельзя писать логику получения запросов.
А авторы pinia в своей документации утверждают, что можно и нужно. И я им верю больше.
Если вы верите, то вера - это уже не дискуссионный вопрос. Просто вот в этом моменте мы с вами не согласимся.
Для меня что бы авторы Pinia не утверждали, я беру их библиотеку, чтобы во Vue приложении у меня было общее реактивное хранилище.
Если оно мне не нужно как общее, а нужно в каком-то одном месте, то я считаю, что и логика работы должна быть описана где-то рядом с местом использования. Т.е. за разбивание логики работы приложения сначала по бизнес-фичам, а уже потом по функционалу.
Можно внутри productStore сделать переменную типа Map, где ключ - тип списка, а значение - собственно список
Ок, логика понятна, про такой подход спор далее будет уже скорее религиозный, поэтому предлагаю прекратить.
Единствнный вопрос - вы бы для этой переменной типа Map использовали ref или shallowRef? И вообще в сторах вы списки и объекты в каком виде храните - в виде ref или shallowRef?
В начале обсуждения такого условия не ставилось. А оно принципиальное.
Так и в жизни так же, сначала такое условие не ставится, а потом может и поставиться.
Т.е., допустим, у нас есть сторы сущностей user, product, orders. Мы по вашей логике храним эти сущности в сторах, через сторы запрашиваем.
Далее пришла задача получать не только основной список products и отображать его, но одновременно с этим отображать список поменьше - featured products.
Тут мы либо переносим логику получения товаров в компоненты, у каждого свой список, но тогда архитектура приложения в плане работы со списками будут разной - user, orders - хранятся в сторе, а логика работы с products переносится в компоненты. Либо мы в сторе для product имеем 2 списка и загружаем их двумя методами. Но зачем это делать, если каждый список нужен своему компоненту?
А потом еще прилетит задача убрать компонент featured products - удалим ли мы список получения товаров для него из стора или забудем и тогда он останется там до тех пор, пока кто-то за глобальный рефакторинг не возьмется?
Если нет задачи отображать на экране несколько списков сразу - то я не понимаю, зачем вы пишите про дублирование списков внутри стора
Так задачи может изначально не быть, потом она может появиться, не лучше ли такой момент предусмотреть и сразу не использовать такую архитектуру?
Или, если вам так важно, при вызове метода в сервисе, который загрузит данные а потом вызовет метод стора, и скопирует их в него.
Тут получается такая странная штука:
Компонент вызывает сервис
Сервис кладет данные в стор
Компонент берет данные из стора
Т.е. запрос для получения идет в сервис, а данные приходит из стора. Логичнее было бы:
Компонент просит данные у сервиса
Сервис откуда-то их берет (бэк, кэш, его дело) и отдает компоненту.
для меня очень странно, когда стор используют для получения каких-то сущностей с бэка (например, товаров), прописывают там логику с fetch и т.д., а потом используют это только в одном компоненте.
Вы отвечаете:
Вполне нормальный подход. Считаем стор единственным местом хранения данных. Все взаимодействие с бэком - скрыто внутри стора
Теперь вы же:
В таком случае стор вообще не нужен )
Грузите сразу из сервиса в компонент, раз кроме него, они нигде не требуются.
Ну то есть у вас реально не было задач, когда одни и те же данные должны использоваться несколькими компонентами?
Прочитайте, о чем я пишу. Я пишу о списках сущностей, которые используются в одном компоненте. Я нигде не писал, что стор не нужен для общих данных!!!!!!!!!!!!!!!!!!!
Actions ... are perfect to define business logic:
Тут обсуждаемая статья как раз про то, что использовать формат Option Store - устаревший формат. И я с автором соглашусь.
И не должны компоненты знать ничего о способе общения с сервером.
Как и сторы, для этого отдельные сервисы используются.
А уже внутри этого метода может быть как общая бизнес-логика...
Может быть, и у меня иногда она есть, но все-таки лучше для этого использовать отдельные сервисы.
Паттерн Active Record тоже его формально нарушает, при этом применяется в каждом втором проекте для веба
Но при этом и проблем приносит, не зря в крупных проектах с данными работают чаще иным образом.
Я не понимаю контекст вашего ответа, явно вы отвечаете не на мои комментарии.
То есть, некий класс, который внутри себя использует стор и сервис взаимодействия с сервером (2 зависимости) - это хорошо?
Почему класс, который внутри себя использует стор? Я предлагаю использовать компонент, который будет запрашивать данные у сервиса и хранить их в себе.
А стор, который использует внутри себя сервис взаимодействия с сервером (1 зависимость) - это плохо?... S из solid не нарушается.
У стора S - это хранение данных, ну и плюсом идет каким-то образом их изменение. Когда он отвечает за запросы к серверу - это уже нарушение Single Responsibility Principle.
Хотя могу предположить, что у вас просто не было по настоящему сложных хранимых на клиентской стороне взаимозависимых структур данных
Да, откуда мне их взять-то, железная логика. Перечитайте мои комменты, про что я писал. Лень дублировать.
Внутри стора нельзя писать логику получения запросов. Для этого есть сервисы.
Т.е. по вашей логике когда компоненту надо что-то получить с бэка, он дергает сервис, а результат берет из стора? Или все таки он запрос делает к стору и стор берет данные из сервиса, но тогда уже получается не сильно важно стор делает fetch(...) или что-то типа userService.fetchList(...).
консистентность - данные с Бека хранятся в одном месте
Так в том и проблема, что в случае списков не всем компонентам нужна консистентность. Например одному компоненту нужны товары с сортировкой по цене по 20 на страницу. Сделали с хранением в сторе. А теперь задача возникла, что другой компонент должен отображать те же сущности товаров, но самые новые, и их всего 5. Для этого придется в сторе заводить еще список, консистентность тут наоборот создает проблему.
удобство тестов - можно легко мокать стор (попробуйте замокать локальную переменную где-то в сервисе)
Так тестируйте сервис.
удобная отладка - просмотр содержимого стора
Содержимое компонента тоже удобно отлаживается. И самое главное, в его внутреннее содержимое ничего не попадет из того, что он сам не запросит. А если несколько компонентов могут менять стор, то в некоторых случаях еще отлови попробуй, какой из них его поменял.
Например. Есть форум. В нем есть обычная модалка для редактирования профиля пользователя...
Я не писал про профиль пользователя, я писал про списки сущностей, которые можно получать в т.ч. с пагинацией, фильтрами, сортировкой и т.д..
кто вообще сказал, что стор должен обслуживать только один компонент
И кто, простите, такое сказал? Точно не я.
что плохого в том, что он умный?
Прочитайте про God-классы, чем они плохи. Примерно тем же плохи и умные сторы и все прочее. Комментарием выше @Pubert, также споря со мной, при этом пишет:
Внутри стора нельзя писать логику получения запросов...
Если данные нужны только в 1 компоненте, то логика получается размазана между стором и компонентом, хотя логично было бы хранить ее рядом с компонентом, которому она нужна
Если список тех же сущностей понадобится другому компоненту, но уже с другими фильтрами, сортировкой и т.п., то придется дублировать стор.
Стор перестает быть тупым и начинает отвечать за запросы и их состояние, вместо того, чтобы просто сохранять и отдавать.
Ещё для меня очень странно, когда стор используют для получения каких-то сущностей с бэка (например, товаров), прописывают там логику с fetch и т.д., а потом используют это только в одном компоненте.
Такая практика часто встречается в различных туториалах по Vue.
Excited for our first DevDay Exchange event in India 🇮🇳 on November 4. Ahead of that, we have some exciting updates coming for India users over the next couple of weeks. Stay tuned!
Не запустила, а запустит, следите за новостями в ближайшие пару недель.
Те преимущества, что вы описали - это про скорость. Микросервисы на Go - милое дело, но вот сложные штуки, где важна скорость разработки, но не в ущерб архитектуре, и есть множество готовых решений для ее ускорения, Rust и Go по-моему в пролете. А PHP с Node.js - вполне себе оправданные решения.
Про Java и C# не сильно в курсе, но мой вопрос и не про них.
Зачем же его придумали тогда?
Меняться будет только весь список целиком, а не ключи каждого товара, а вы c ref реактивность вешаете на каждый ключ каждого товара, хотя с бэка вообще может прилететь гораздо больше ключей, чем на фронте надо. В итоге память на хранение таких данных увеличивается в разы.
Тут получается, что вы пользователю в разы по сравнению с shallowRef увеличиваете нагрузку на процессор и память, т.к. каждому ключу каждого элемента списка создается прокси, чтобы отслеживать изменения, хотя список-то по сути скорее всего никогда и не изменится.
Ок, я понял вашу логику. Процитирую ваш ответ здесь же другому пользователю:
Если вы верите, то вера - это уже не дискуссионный вопрос. Просто вот в этом моменте мы с вами не согласимся.
Для меня что бы авторы Pinia не утверждали, я беру их библиотеку, чтобы во Vue приложении у меня было общее реактивное хранилище.
Если оно мне не нужно как общее, а нужно в каком-то одном месте, то я считаю, что и логика работы должна быть описана где-то рядом с местом использования. Т.е. за разбивание логики работы приложения сначала по бизнес-фичам, а уже потом по функционалу.
Ок, логика понятна, про такой подход спор далее будет уже скорее религиозный, поэтому предлагаю прекратить.
Единствнный вопрос - вы бы для этой переменной типа Map использовали ref или shallowRef? И вообще в сторах вы списки и объекты в каком виде храните - в виде ref или shallowRef?
Так и в жизни так же, сначала такое условие не ставится, а потом может и поставиться.
Т.е., допустим, у нас есть сторы сущностей user, product, orders. Мы по вашей логике храним эти сущности в сторах, через сторы запрашиваем.
Далее пришла задача получать не только основной список products и отображать его, но одновременно с этим отображать список поменьше - featured products.
Тут мы либо переносим логику получения товаров в компоненты, у каждого свой список, но тогда архитектура приложения в плане работы со списками будут разной - user, orders - хранятся в сторе, а логика работы с products переносится в компоненты. Либо мы в сторе для product имеем 2 списка и загружаем их двумя методами. Но зачем это делать, если каждый список нужен своему компоненту?
А потом еще прилетит задача убрать компонент featured products - удалим ли мы список получения товаров для него из стора или забудем и тогда он останется там до тех пор, пока кто-то за глобальный рефакторинг не возьмется?
Так задачи может изначально не быть, потом она может появиться, не лучше ли такой момент предусмотреть и сразу не использовать такую архитектуру?
Тут получается такая странная штука:
Компонент вызывает сервис
Сервис кладет данные в стор
Компонент берет данные из стора
Т.е. запрос для получения идет в сервис, а данные приходит из стора. Логичнее было бы:
Компонент просит данные у сервиса
Сервис откуда-то их берет (бэк, кэш, его дело) и отдает компоненту.
Мой изначальный коммент:
Вы отвечаете:
Теперь вы же:
Отвечу сразу на оба ваших комментария.
Прочитайте, о чем я пишу. Я пишу о списках сущностей, которые используются в одном компоненте. Я нигде не писал, что стор не нужен для общих данных!!!!!!!!!!!!!!!!!!!
Тут обсуждаемая статья как раз про то, что использовать формат Option Store - устаревший формат. И я с автором соглашусь.
Как и сторы, для этого отдельные сервисы используются.
Может быть, и у меня иногда она есть, но все-таки лучше для этого использовать отдельные сервисы.
Но при этом и проблем приносит, не зря в крупных проектах с данными работают чаще иным образом.
Т.е. вы предлагаете несколько тысяч товаров загрузить клиенту за 1 запрос (а может и десятков тысяч), а потом браузером работать с этим списком?
Я не понимаю контекст вашего ответа, явно вы отвечаете не на мои комментарии.
Почему класс, который внутри себя использует стор? Я предлагаю использовать компонент, который будет запрашивать данные у сервиса и хранить их в себе.
У стора S - это хранение данных, ну и плюсом идет каким-то образом их изменение. Когда он отвечает за запросы к серверу - это уже нарушение Single Responsibility Principle.
Да, откуда мне их взять-то, железная логика. Перечитайте мои комменты, про что я писал. Лень дублировать.
Т.е. по вашей логике когда компоненту надо что-то получить с бэка, он дергает сервис, а результат берет из стора? Или все таки он запрос делает к стору и стор берет данные из сервиса, но тогда уже получается не сильно важно стор делает fetch(...) или что-то типа userService.fetchList(...).
Так в том и проблема, что в случае списков не всем компонентам нужна консистентность. Например одному компоненту нужны товары с сортировкой по цене по 20 на страницу. Сделали с хранением в сторе. А теперь задача возникла, что другой компонент должен отображать те же сущности товаров, но самые новые, и их всего 5. Для этого придется в сторе заводить еще список, консистентность тут наоборот создает проблему.
Так тестируйте сервис.
Содержимое компонента тоже удобно отлаживается. И самое главное, в его внутреннее содержимое ничего не попадет из того, что он сам не запросит. А если несколько компонентов могут менять стор, то в некоторых случаях еще отлови попробуй, какой из них его поменял.
Я не писал про профиль пользователя, я писал про списки сущностей, которые можно получать в т.ч. с пагинацией, фильтрами, сортировкой и т.д..
И кто, простите, такое сказал? Точно не я.
Прочитайте про God-классы, чем они плохи. Примерно тем же плохи и умные сторы и все прочее. Комментарием выше @Pubert, также споря со мной, при этом пишет:
А какие плюсы-то у такой логики?
Минусы вот следующие:
Если данные нужны только в 1 компоненте, то логика получается размазана между стором и компонентом, хотя логично было бы хранить ее рядом с компонентом, которому она нужна
Если список тех же сущностей понадобится другому компоненту, но уже с другими фильтрами, сортировкой и т.п., то придется дублировать стор.
Стор перестает быть тупым и начинает отвечать за запросы и их состояние, вместо того, чтобы просто сохранять и отдавать.
Ещё для меня очень странно, когда стор используют для получения каких-то сущностей с бэка (например, товаров), прописывают там логику с fetch и т.д., а потом используют это только в одном компоненте.
Такая практика часто встречается в различных туториалах по Vue.
Такие штуки вообще часто имеет смысл подключать через intersection observer, когда пользователь доскроллит уже ближе к нужному элементу.
Не запустила, а запустит, следите за новостями в ближайшие пару недель.
Пока еще ничего не дают, только покупка.
Спасибо. В целом очень неплохо, принимая во внимание, сколько бы занимало было на Electron.
Интересно узнать, сколько примерно занимает HelloWorld на нем на разных OS?
Те преимущества, что вы описали - это про скорость. Микросервисы на Go - милое дело, но вот сложные штуки, где важна скорость разработки, но не в ущерб архитектуре, и есть множество готовых решений для ее ускорения, Rust и Go по-моему в пролете. А PHP с Node.js - вполне себе оправданные решения.
Про Java и C# не сильно в курсе, но мой вопрос и не про них.
Почему вы считаете, что на Go и Rust лучше писать сложный бэк?
Так все, что в белый список не попало, блокируется. У перечисленных сервисов не прямо уж все-все IP в белом списке.
У меня однажды отвалился то ли крон, то ли скрипт автообновления сертификата. Вот тогда письмо помогло.