- PVSM.RU - https://www.pvsm.ru -
Как я уже писал в своих предыдущих статьях я работал и с polymer [1] и с vue [2] в связке с redux [3]. Поэтому хотелось бы поделиться опытом, связанным со спецификой использования redux [4] в данных библиотеках. Рассматривать будем на простейших атомарных контролах: нативных (input, checkbox) и обернутых, в виде компонентов данных библиотек.
В статье я опуская описание настройки интеграции redux
с polymer [5] и vue [2], а так же описание азов самого redux, дабы не эту тему хочу раскрыть в статье.
Сначала вспомним один из основных принципов redux [6]:
The only way to change the state is to emit an action, an object describing what happened.
Исходя из него ясно, что напрямую мы не можем изменить состояние, а сделать это можем только через диспатч экшена после наступление необходимого event'а.
Схематично это можно изобразить так:
Как видим наблюдается односторонний поток данных.
Очень удобная вещь в 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
и контрол перерендерится уже с новым значением.
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
.
С компонентами сложней, так как это совокупность методов, событий, «завернутые» в компоновку html
-элементов в виде шаблона.
Схематичное описание работы компонента:
Как видим о событии компонента мы узнаем уже обо всем постфактум, что противоречит принципу redux
описанному выше. И что бы избежать неконсистентной ситуации, когда контрол уже перерендерился в виду своего внутреннего состояния, а прибинденная модель еще не поменялась через action
и не соответствует данному представлению необходимо производить дополнительные действия для блокировки прямого изменения state.
На примере компонента 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);
}
На примере компонента 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
Нажмите здесь для печати.