- PVSM.RU - https://www.pvsm.ru -

Специфика использования Redux в Polymer и Vue

Специфика использования Redux в Polymer и Vue - 1
Как я уже писал в своих предыдущих статьях я работал и с polymer [1] и с vue [2] в связке с redux [3]. Поэтому хотелось бы поделиться опытом, связанным со спецификой использования redux [4] в данных библиотеках. Рассматривать будем на простейших атомарных контролах: нативных (input, checkbox) и обернутых, в виде компонентов данных библиотек.
В статье я опуская описание настройки интеграции redux с polymer [5] и vue [2], а так же описание азов самого redux, дабы не эту тему хочу раскрыть в статье.

0. Введение

Сначала вспомним один из основных принципов redux [6]:

The only way to change the state is to emit an action, an object describing what happened.

Исходя из него ясно, что напрямую мы не можем изменить состояние, а сделать это можем только через диспатч экшена после наступление необходимого event'а.
Схематично это можно изобразить так:
Специфика использования Redux в Polymer и Vue - 2
Как видим наблюдается односторонний поток данных.

1. Нативные контролы

polymer

Очень удобная вещь в polymer при связке с redux дак это односторонний биндинг [7].

template:

<input value="[[propFromReduxStore]]" on-change="changeText"></input>

js-code:

changeInput: function(e) {
  this.dispatch("setText", e.currentTarget.value);
}

Поэтому с input все, в принципе стандартно: при событии change диспатчим action [8] и после чего измененное значение попадает в propFromReduxStore и контрол перерендерится уже с новым значением.

vue

C vue немного другая ситуация, в нем нет как такагого одностороннего биндинга, как в polymer. Но подобную функциональность можно достигнуть через модификатор sync [9]

template:

<input :value.sync="propFromReduxStore" @change="changeText"></input>

js-code:

changeInput: function(e) {
  this.actionsRedux("setText", e.currentTarget.value);
}

Остальное все как и в варианте с polymer.

2. Компоненты

С компонентами сложней, так как это совокупность методов, событий, «завернутые» в компоновку html-элементов в виде шаблона.
Схематичное описание работы компонента:
Специфика использования Redux в Polymer и Vue - 3
Как видим о событии компонента мы узнаем уже обо всем постфактум, что противоречит принципу redux описанному выше. И что бы избежать неконсистентной ситуации, когда контрол уже перерендерился в виду своего внутреннего состояния, а прибинденная модель еще не поменялась через action и не соответствует данному представлению необходимо производить дополнительные действия для блокировки прямого изменения state.

polymer

На примере компонента paper-checkbox [10]

template:

<paper-checkbox checked="[[propFromReduxStore]]" on-tap="changeCheck"></paper-checkbox>

js-code:

changeCheck: function(e) { //Здесь ловим клик по компоненту
  //Предотвращаем bubbling события, что бы компонент сразу не перерендерил компонент 
  e.stopPropagation();
  this.dispatch("setChecked", !this.propFromReduxStore);
}

vue

На примере компонента el-checkbox [11]

template:

<el-checkbox v-model="propFromReduxStore" @click.stop.native="changeCheck" >
</el-checkbox>

js-code:

changeCheck: function() {
this.actionsRedux("setChecked", !this.propFromReduxStore);
}

В компоненте может даже и не быть события click, а если и есть, то узнаем мы об его наступлении уже постфактум, не говоря уже об его подалении, но зато есть модификатор native [12], который позволяет получить доступ ко всем возможным нативным событиям [13]. Так же есть модификатор [14] stop, который даже позволит нам не писать e.stopPropagation(), как это было с polymer. Малость, а приятно.

React не рассмотрел, так как на практике его не использовал, если не считать jsx-темплейтов в vue, но это совершенно не то. Но все-таки, насколько я наслышен от коллег по цеху, там таких проблем нет, в виду внутренней архитектуры обработки событий.

Автор: Анатолий

Источник [15]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/javascript/263594

Ссылки в тексте:

[1] polymer: https://habrahabr.ru/post/333660/

[2] vue: https://habrahabr.ru/post/336352/

[3] redux: https://habrahabr.ru/post/335868/

[4] redux: http://redux.js.org/

[5] polymer: https://github.com/tur-nr/polymer-redux

[6] один из основных принципов redux: http://redux.js.org/docs/introduction/ThreePrinciples.html#state-is-read-only

[7] односторонний биндинг: https://www.polymer-project.org/1.0/docs/devguide/data-system#data-flow-is-synchronous

[8] action: http://redux.js.org/docs/basics/Actions.html#action-creators

[9] модификатор sync: https://ru.vuejs.org/v2/guide/components.html#%D0%9C%D0%BE%D0%B4%D0%B8%D1%84%D0%B8%D0%BA%D0%B0%D1%82%D0%BE%D1%80-sync

[10] paper-checkbox: https://www.webcomponents.org/element/PolymerElements/paper-checkbox

[11] el-checkbox: http://element.eleme.io/#/en-US/component/checkbox

[12] native: https://ru.vuejs.org/v2/guide/components.html#%D0%9F%D0%BE%D0%B4%D0%BF%D0%B8%D1%81%D0%BA%D0%B0-%D0%BD%D0%B0-%D0%BD%D0%B0%D1%82%D0%B8%D0%B2%D0%BD%D1%8B%D0%B5-%D1%81%D0%BE%D0%B1%D1%8B%D1%82%D0%B8%D1%8F-%D0%B2-%D0%BA%D0%BE%D0%BC%D0%BF%D0%BE%D0%BD%D0%B5%D0%BD%D1%82%D0%B0%D1%85

[13] нативным событиям: https://www.w3schools.com/js/js_events.asp

[14] модификатор: https://ru.vuejs.org/v2/guide/events.html#%D0%9C%D0%BE%D0%B4%D0%B8%D1%84%D0%B8%D0%BA%D0%B0%D1%82%D0%BE%D1%80%D1%8B-%D1%81%D0%BE%D0%B1%D1%8B%D1%82%D0%B8%D0%B9

[15] Источник: https://habrahabr.ru/post/337564/?utm_source=habrahabr&utm_medium=rss&utm_campaign=best