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

в 19:23, , рубрики: Events, javascript, polymer.js, redux, state, vue.js, Программирование, Разработка веб-сайтов

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

0. Введение

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

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 дак это односторонний биндинг.

template:

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

js-code:

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

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

vue

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

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

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

template:

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

js-code:

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

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

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

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

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js