Как стать автором
Обновить

Комментарии 28

НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
Как опытный человек посоветуйте, как лучше организовать работу с данными.

Вот банально: есть табличка с пользователями и есть редактор атрибутов пользователя. Хочется, чтобы после изменения атрибута табличка это замечала.

Неужели придется во vuex все держать? Потенциально сотни строк данных?
Сотни строк данных это не самый большой объем, вообще говоря.
Я на своем петпроекте обычно держу в состоянии приложения только срез данных. Например, если у меня есть табличка с юзерами, то подгружается она постранично, и если из вебсокетов приходит сообщение об изменении пользователя (например, он вошел в сеть), то в хранилище вносятся изменения только если пользователь есть на этой условной странице.
Аналогично ведется работа с другими многочисленными сущностями — комментариями, новостями итд. Приложение и его стор не должны превращаться в копию бд на клиенте.
Не претендую на правильность, так как новичок, да и Вью использую, в основном, для собственных проектов, но для себя подобную логику выношу в отдельный модуль (например класс), дальше передаю этот модуль через vuex (достаточно просто стейта). Ну и в других компонентах мы точно получаем доступ к одному и тому же экземпляру класса.
Эм что?
1. No comments. С таким подходом не пишите код. Завтра вы его всё равно забудете.
2. Он в отличии от других подобных плюшек собирает себя только в тех рамках в которых вы его используете. Не нравится часть компонентов, просто не используй. В конечном бандле они не будут принимать участия.
3. Прямо сейчас работаю с Канадцами и меня всё ещё заставляют писать под IE 11 и IOS9. Это экономически обосновано. Нам всем надо с рынка уходить и оставить клиентов на таких как вы, «Купи новый айфон, ты чё как бомж»? И это на секундочку Канада.

Не использование vuex прямой путь получить кучу не работающей реактивности и мутного кода который не понятно как вызывается. Мы до сих пор разгребаем проект, где часть кода написана была без vuex, постепенно проводя рефакторинг. И о чудо, где вставляется vuex тут же начинает нормально работать реактивность где она не работала.

Если в проекте намешаны два подхода, то понятно, что будет беда. Но вот у меня на проекте vuex совсем не прижился. Совершенно другая философия у него, в отличии от vue. Был полностью выпилен и сейчас без него прикрасно живётся. Компонентов много, в роутинге под 300 типов страниц, эндпоинтов очень много, всё прекрасно живёт без vuex.

Хм. А что используется в место него? И как вообще устроена архитектура?

Смею предположить, что используются providers.
image
Используется шина данных в виде инстанса vue. Там ооочень мало данных, которые нужны прямо всем приложениям. Я сторонник подхода, чтобы состояние хранилось в урле и из неё же инициализировалось. Остальное мы либо храним в шине (например очередб уведомлений) либо не храним вообще (типа недозаполненный инпут у неотправленной формы)
Ну если у вас данных столько что можно хранить в урле, то это один разговор. И понятно что махину подключать ради 2х параметров не стоит. Я думаю мы все тут (по умолчанию) думали об ситуациях чуток по сложнее.
Я бы еще добавил — сразу используйте тайпскрипт.
Попытался я как-то вьюшный проект на тс перевести. Больше не буду пытаться.
Жду выхода вью3, чтобы уже точно можно было на прод катить, и обязательно буду на него всё переписывать уже с нормальной поддержкой тайпскрипта. Без тс прям тоскливо.
А какие сложности основные? Два года назад взяли связку TS + Vue и сейчас весь проект на ней.
Недавно перевел средних размеров проект (страниц штук 40, своя библиотека базовых компонентов) на тайпскрипт и стайлус. Ничего особенно сложного, а поддержка тайпскрипта вполне бодрая.
Единственное что меня как олда подбешивает — это отсутствие хоть одной удобной тулзы для валидации форм. После, простите, jquery.unobtrusive.validate все выглядит громоздким и при этом черновым.
Используем vee-validate, в целом всё устраивает

Пробовал его и не понравилось, но сейчас в доках вижу что-то новое. Спасибо, попробую.

А в чем конкретно проблема была?
Писали несколько крупных приложений с 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, если всё равно всё в js соберётся. Классы опять же никуда не денусть и в тройке можно будет так же писать. (Отказались от своего Class API предложения)
Ну и мне проще работать с классами как я это делаю в других языках.

Структуру VueX можно настроить более детально. Например: не хранить все геттеры в одном файле, а делить их в зависимости от функционала (store-folder->news-folder->news-getters.js). Тоже самое и с экшенами, мутациями и состояниями, так будет удобнее управлять хранилищем и не копаться в одном файле, где овер 5к строк, чтобы найти необходимое

А можно у стора сделать namespaced: true,:
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();
Тот случай, когда комментарии полезнее статьи.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий