vue mixinsНедавно перешел с PolymerJS на VueJS для некоторых задач. Совместно с polymer использовал Redux через библиотеку polymer-redux. Поэтому вся бизнес-логика уже была сформирована на уровне redux store. Для связки vue и redux выбрал библиотеку vuedeux. В awesome vue в разделе redux представлена еще одна библиотека для связки с redux — revue, но мне показалось эффективней использовать именно vuedeux, за счет интеграции redux store непосредственно в «свой redux» для vue vuex, для возможного использования его в будущем.

После создание vuex store, используя плагин vuedeux доступ к необходимым разделам redux store может быть осуществлен через computed свойства экземпляра vue-компонента. Например, вот так (часть кода из examples):

...
 computed: {
    todos () {
      return this.$store.state.redux.todos
    },
    ...
  }
...

А action creators попадают в экземпляр компонента через раздел data, например:

new Vue({
 ...
  data: {
    reduxActions: actionCreators,
  },
 ...
});

Диспатчить экшены можно, например, так:

methods: {
    addTodo () {
        this.$store.dispatch(this.$root.reduxActions.addingTodo(text))
    },
    ...
}

Остальные action creators можно «прокинуть» напрямую в раздел methods:


methods: {
  ...mapActions({
        toggleAll: 'COMPLETE_ALL',
        clearCompleted: 'CLEAR_COMPLETED'
  }),
  ...
}

Но как по мне это не очень удобно для использования, так как все action creators будут в корне контекста экземпляра компонента. И при их использовании будет не совсем понятно этот метод диспатчит экшен или просто выполняет какие-либо внутренние действия компонента. А хотелось бы сразу понимать, что данный метод является action creators.

Для этих целей я разработал миксин redux-store-mixin для интеграции с redux actions через единую точку входа в виде метода reduxActions aka метод dispatch из вышеупомянутой библиотеки polymer-redux.

Использование


Подключаем сам миксин:

import reduxStoreMixin from "redux-store-mixin"; 

Подключаем свои action creators:

import {actionCreators} from "store/store";

И подключаем метод mapState из vuex для удобного «прокидывания» необходимых свойств из redux store:

import { mapState } from "vuex";

И создаем экземпляр vue-компонента с миксином и необходимыми свойствами:

new Vue({
  mixins: [
                ...
		reduxStoreMixin(actionCreators),
                ...
  ],
  computed: {
		...mapState({
			prop1: state => state.redux.map.prop1,
                        ...
                        propN: state => state.redux.map.propN
                 }),
                 ...
  },
  ...
});

После этого вызов экшена будет выглядеть следующим образом:

this.reduxActions(<name action creator>, ...args);

где name action creator — наименование «action creator»-функции,
...args — перечень аргументов для ее вызова.

Всю прелесть данного метода особенно прочувствуют те, кто пользовался библиотекой polymer-redux.

Заключение


Подобные миксины уже существует, например: Vue-Redux-Mixin-Generator и vue-redux-mixin. Но по сравнению с ними мое решение имеет более простую настройку и более наглядно в использовании, с учетом, что интеграция vue и redux будет осуществлена через vuedeux.

GitHub

Комментарии (4)


  1. r-moiseev
    05.09.2017 01:46
    +2

    Я не понял. А зачем redux если vuex уже есть? Я чего то не понимаю, или vuex это и есть клон redux?


    1. kolesoffac Автор
      05.09.2017 09:50
      +2

      Да в таком случаи редакс не нужен, но я в начале написал, что я переходил с polymer, и вся бизнес-логика уже была реализована в редакс-сторе, поэтому, что бы ускорить переход на vue я пока интегрировал уже имеющийся редакс стор в vuex. При последующих разработках уже возможно перейду на vuex.


  1. eyeofhell
    05.09.2017 11:34

    Если не секрет, для каких задач с Polymer на Vue перешли? Где оно лучше оказалось?


    1. kolesoffac Автор
      05.09.2017 12:35
      +3

      Честно говоря, у них во второй версии оказался баг с dom-repeat, но и в 1.9.2 тоже была проблема. Были фризы при работе — на dom-repeat были повешены вкладки и в контенте каждой вкладке была таблица с динамически сформированными столбцами. И вот после открытия трех вкладок, например, при закрытии одной из них, были фризы на несколько минут. Профилинг показал, что 90% занимает скриптинг, и на самом деле там происходило перезапись модели с одного айтема на другой и что триггерило очень много ивентов рендеринга. Вообщем победить мне это не удалось. Конечно реализация ваадин грида(единственного готового грида на полимере) может быть хромала, поэтому так и выходило, но с нуля писать свой грид мне не захотелось, поэтому решил попробовать vue, тк слышал много положительного об нем. И он не подвел, теперь такого нет(грид бутстрапа), работает все шустренько.