Comments 28
Как опытный человек посоветуйте, как лучше организовать работу с данными.
Вот банально: есть табличка с пользователями и есть редактор атрибутов пользователя. Хочется, чтобы после изменения атрибута табличка это замечала.
Неужели придется во vuex все держать? Потенциально сотни строк данных?
Вот банально: есть табличка с пользователями и есть редактор атрибутов пользователя. Хочется, чтобы после изменения атрибута табличка это замечала.
Неужели придется во vuex все держать? Потенциально сотни строк данных?
Сотни строк данных это не самый большой объем, вообще говоря.
Я на своем петпроекте обычно держу в состоянии приложения только срез данных. Например, если у меня есть табличка с юзерами, то подгружается она постранично, и если из вебсокетов приходит сообщение об изменении пользователя (например, он вошел в сеть), то в хранилище вносятся изменения только если пользователь есть на этой условной странице.
Аналогично ведется работа с другими многочисленными сущностями — комментариями, новостями итд. Приложение и его стор не должны превращаться в копию бд на клиенте.
Я на своем петпроекте обычно держу в состоянии приложения только срез данных. Например, если у меня есть табличка с юзерами, то подгружается она постранично, и если из вебсокетов приходит сообщение об изменении пользователя (например, он вошел в сеть), то в хранилище вносятся изменения только если пользователь есть на этой условной странице.
Аналогично ведется работа с другими многочисленными сущностями — комментариями, новостями итд. Приложение и его стор не должны превращаться в копию бд на клиенте.
Не претендую на правильность, так как новичок, да и Вью использую, в основном, для собственных проектов, но для себя подобную логику выношу в отдельный модуль (например класс), дальше передаю этот модуль через vuex (достаточно просто стейта). Ну и в других компонентах мы точно получаем доступ к одному и тому же экземпляру класса.
Эм что?
1. No comments. С таким подходом не пишите код. Завтра вы его всё равно забудете.
2. Он в отличии от других подобных плюшек собирает себя только в тех рамках в которых вы его используете. Не нравится часть компонентов, просто не используй. В конечном бандле они не будут принимать участия.
3. Прямо сейчас работаю с Канадцами и меня всё ещё заставляют писать под IE 11 и IOS9. Это экономически обосновано. Нам всем надо с рынка уходить и оставить клиентов на таких как вы, «Купи новый айфон, ты чё как бомж»? И это на секундочку Канада.
1. No comments. С таким подходом не пишите код. Завтра вы его всё равно забудете.
2. Он в отличии от других подобных плюшек собирает себя только в тех рамках в которых вы его используете. Не нравится часть компонентов, просто не используй. В конечном бандле они не будут принимать участия.
3. Прямо сейчас работаю с Канадцами и меня всё ещё заставляют писать под IE 11 и IOS9. Это экономически обосновано. Нам всем надо с рынка уходить и оставить клиентов на таких как вы, «Купи новый айфон, ты чё как бомж»? И это на секундочку Канада.
Не использование vuex прямой путь получить кучу не работающей реактивности и мутного кода который не понятно как вызывается. Мы до сих пор разгребаем проект, где часть кода написана была без vuex, постепенно проводя рефакторинг. И о чудо, где вставляется vuex тут же начинает нормально работать реактивность где она не работала.
Если в проекте намешаны два подхода, то понятно, что будет беда. Но вот у меня на проекте vuex совсем не прижился. Совершенно другая философия у него, в отличии от vue. Был полностью выпилен и сейчас без него прикрасно живётся. Компонентов много, в роутинге под 300 типов страниц, эндпоинтов очень много, всё прекрасно живёт без vuex.
Хм. А что используется в место него? И как вообще устроена архитектура?
Смею предположить, что используются providers.
А я про vue2 provide-inject
Используется шина данных в виде инстанса vue. Там ооочень мало данных, которые нужны прямо всем приложениям. Я сторонник подхода, чтобы состояние хранилось в урле и из неё же инициализировалось. Остальное мы либо храним в шине (например очередб уведомлений) либо не храним вообще (типа недозаполненный инпут у неотправленной формы)
Я бы еще добавил — сразу используйте тайпскрипт.
Попытался я как-то вьюшный проект на тс перевести. Больше не буду пытаться.
Жду выхода вью3, чтобы уже точно можно было на прод катить, и обязательно буду на него всё переписывать уже с нормальной поддержкой тайпскрипта. Без тс прям тоскливо.
Жду выхода вью3, чтобы уже точно можно было на прод катить, и обязательно буду на него всё переписывать уже с нормальной поддержкой тайпскрипта. Без тс прям тоскливо.
А какие сложности основные? Два года назад взяли связку TS + Vue и сейчас весь проект на ней.
Недавно перевел средних размеров проект (страниц штук 40, своя библиотека базовых компонентов) на тайпскрипт и стайлус. Ничего особенно сложного, а поддержка тайпскрипта вполне бодрая.
Единственное что меня как олда подбешивает — это отсутствие хоть одной удобной тулзы для валидации форм. После, простите, jquery.unobtrusive.validate все выглядит громоздким и при этом черновым.
Единственное что меня как олда подбешивает — это отсутствие хоть одной удобной тулзы для валидации форм. После, простите, jquery.unobtrusive.validate все выглядит громоздким и при этом черновым.
Используем vee-validate, в целом всё устраивает
А в чем конкретно проблема была?
Писали несколько крупных приложений с 0 на тс — все было отлично. Переводить, правда, не пробовали…
Писали несколько крупных приложений с 0 на тс — все было отлично. Переводить, правда, не пробовали…
С typescript есть куча приятных мелочей, например vuex-module-decorators.
Стор:
Модуль:
В любом компоненте можно получить доступ так:
Стор:
import Vue from 'vue';
import Vuex from 'vuex';
import VuexPersistence from 'vuex-persist';
import { AppState } from 'src/store/modules/app';
Vue.use(Vuex);
export interface RootState {
'app': AppState
}
const vuexLocal = new VuexPersistence<RootState>({
storage: window.localStorage,
reducer: (state) => ({
app: state.app,
}),
});
const store = new Vuex.Store<RootState>({
strict: process.env.DEV === 'true',
plugins: [vuexLocal.plugin],
});
export function checkModuleStateExists(moduleName: string): boolean {
const savedState = localStorage.getItem('vuex');
if (!savedState) {
return false;
}
return JSON.parse(savedState)[moduleName] != null;
}
export default store;
Модуль:
export interface AppState {
drawerIsOpen: boolean
}
@Module({
dynamic: true,
name: 'app',
namespaced: true,
stateFactory: true,
store: Store,
preserveState: checkModuleStateExists('app'),
})
export class AppStoreModule extends VuexModule implements AppState {
public drawerIsOpen: boolean = true;
}
export default getModule(AppStoreModule);
В любом компоненте можно получить доступ так:
<script lang="ts">
import { Vue, Component } from 'vue-property-decorator';
import AppModule, { AppStoreModule } from 'src/store/modules/app';
import { getModule } from 'vuex-module-decorators';
@Component
export default class MainLayout extends Vue {
app = getModule(AppStoreModule);
get drawerIsOpen(): boolean {
return AppModule.drawerIsOpen;
/// или
return this.app.drawerIsOpen;
}
}
</script>
Vue 2 весьма плохо оптимизирован по TS. Настоятельно рекомендую быстрее переходить на Composition API еще до выхода Vue 3, благо на это есть библиотека от создателей.
Намного проще и удобнее выносить все в чистые функции TS и просто импортировать в Vue 3 компоненты.
Намного проще и удобнее выносить все в чистые функции TS и просто импортировать в Vue 3 компоненты.
Структуру VueX можно настроить более детально. Например: не хранить все геттеры в одном файле, а делить их в зависимости от функционала (store-folder->news-folder->news-getters.js). Тоже самое и с экшенами, мутациями и состояниями, так будет удобнее управлять хранилищем и не копаться в одном файле, где овер 5к строк, чтобы найти необходимое
А можно у стора сделать namespaced: true,:
и подрубать через
import Articles from './modules/articles';
и юзать:
ну а если в разных сторах совпадают геттеры/мутации или экшоны, то можно так:
и обращаться соответственно
export default {
namespaced: true,
state: {},
mutations: {},
actions: {},
getters: {}
}
и подрубать через
import Articles from './modules/articles';
export default new Vuex.Store({
modules: {
Articles
}
})
и юзать:
...mapGetters('Articles', ['getter1', 'getter2']),
...mapActions('Articles', ['action1', 'action2'])
...mapMutations('Articles', ['mutation1', 'mutation2'])
ну а если в разных сторах совпадают геттеры/мутации или экшоны, то можно так:
...mapActions('Articles', {
loadArticles: 'load',
}),
...mapActions('Categories', {
loadCategories: 'load',
}),
и обращаться соответственно
this.loadArticles();
this.loadCategories();
Тот случай, когда комментарии полезнее статьи.
Sign up to leave a comment.
4 рекомендации по разработке крупномасштабных проектов на Vue