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

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

Ну и какой смысл сначала делать statefull компоненты, а потом разными трюками превращать их в stateless?


Для связки с redux надо изначально разрабатывать компоненты, которые redux поддерживают. Такой компонент либо должен принимать допустимые действия (action) для изменения своего состояния как параметры, либо он должен иметь возможность объявить свои редьюсеры.

Речь идет не о самописных компонентах, а о сторонних компонентах разных ui(например: element, at-ui). В своих компонентах я могу организовать любой data-workflow, в сторонних компонентах глубоко в код не полезешь, верней можно, но не нужно, поэтому приходится искать пути работы с ними. И вот предлагаю одни из них.

Как правило, самое "вкусное" в сторонних компонентах — состояние и поведение, а не разметка. Выстраивая подобные костыли вокруг чужих компонентов, вы это все вынуждены переписать еще раз.


Ну и в чем в таком случае смысл использования сторонних компонентов? Проще переписать их чем вот так делать.

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

Вы сами-то читали документацию по приведенной вами ссылке? sync — это как раз сахар для имитации двустороннего биндинга. И в вашем примере он не нужен совсем.
А я чего возразил? Я сказал, что прямого одностороннего биндинга как в полимер, например, нет, а есть сахар в виде sync, который обеспечивает этот функционал.
Биндинг во Vue только односторонний (как и в polymer, react, angular 2+). Sync — сахар для обеспечения двустороннего биндинга (как в angularjs). В вашем примере sync не нужен.
P.S. может мы по разному понимаем термин «односторонний биндинг»?
Наверное. Двусторонний — когда изменение могут приходить в прибинденное проперти, как из вне, так и из самого контрола, то есть сам контрол меняет его значение в зависимости от тех или иных событий. И берет эту обработку полностью на себя, то есть про изменение мы узнаем когда изменение уже произойдет — прямое изменение проперти. Как раз этого нам надо избежать. Что бы в контрол данные приходили только из вне, а от контрола мы должны перехватить необходимые события и проксировать их в редак, а из него уже придет в сам контрол, это и есть односторонний бинд.
Вот и я о том же. Однако с sync у вас какая-то путаница. Вот что говорит нам документация на этот счет:
В некоторых случаях нам может понадобиться “двухсторонняя привязка” для входных данных — фактически, в Vue 1.x это было представлено модификатором .sync.

… мы удалили модификатор .sync, когда была выпущена версия 2.0…

В версии 2.3.0+ мы снова ввели модификатор .sync для входных данных, но на этот раз это просто синтаксический сахар, который автоматически преобразуется в дополнительный обработчик v-on

Читаем документацию по вашей же ссылке:


В версии 2.3.0+ мы снова ввели модификатор .sync для входных данных, но на этот раз это просто синтаксический сахар, который автоматически преобразуется в дополнительный обработчик v-on:
Следующее
<comp :foo.sync="bar"></comp>
будет преобразовано в:
<comp :foo="bar" @update:foo="val => bar = val"></comp>

Ну и зачем вам в вашем redux-way обработчик @update:foo="val => bar = val", который напрямую меняет стор? Куда правильнее будет написать этот @update:foo самому, засунув туда dispatch. Заодно можно избавиться от костылей в виде перехвата событий через e.stopPropagation().

Разве я где то описал обработчик update? Я предоставил вариант, который работает на практике, так, как нужно для схемы data-workflow redux'а. sync мне позволяет не синхронизировать значение с прибинденным проперти(понимаю что тавтология, название sync, а используем для того что бы не было синхронизации), а сохранение его во внутреннем стейте самого компонента. Соответсвенно при такой схеме работы мне просто не нужен никакой update.
По поводу костылей, согласен, похоже очень на них, но мне не удалось никак заставить работать нужным образом без них. Буду благодарен любым наводкам на другие подходы.

Вы написали sync — а sync генерирует update, притом не тот что вам нужен. Зачем?


Чем вас не устраивал вот такой вариант:


<input :value="propFromReduxStore" @update:value="changeText"></input>
Генерирует, но он мне не мешает. Можно и таким вариантом, но чем он лучше чем с использование sync?
<input :value.sync="propFromReduxStore" @change="changeText"></input>

Хорошо, а чем ваш вариант лучше вот такого:


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

Неужели вы думаете, что компонент будет как-то по-особому вести себя просто из-за того что у него появился обработчик события?

Нет я так не думаю. Во-первых, я специально разделил на подразделы — работа с нативными контролами, и с компонентами, так как есть своя специфика обработки событий. То что вы написали выше это не компонент, а нативный контрол. И такой вариант не подойдет, по той причине, что все введенные данный сразу попытаются записаться напрямую в propFromReduxStore, а этого делать нельзя. Поэтому нам надо давить данное поведение, или sync или native.
И такой вариант не подойдет, по той причине, что все введенные данный сразу попытаются записаться напрямую в propFromReduxStore, а этого делать нельзя.

Это вы из головы придумали или об этом можно прочитать где-то в документации?

Из головы я ничего не придумываю. Все, что я описал это подходы, полностью работающие на практике, проверенные лично. А почитать например вот. Это обычный подход, как они сами пишут про себя, ненавязчивой реактивности. Но в данном случаи он нам не подходят.

По вашей ссылке я не вижу ничего что подтверждало бы ваши слова.

В чем именно Вы хотите убедиться в документации?
Практические примеры, подтверждают мои слова. Они не теоретически описанные, а пройденные боевое крещение. И не из головы, а из конкретных проектов.

Вот вам практический пример: https://jsfiddle.net/6wpesep0/2/


Из которого следует, что sync применительно к input.value вообще ничего не делает! Это опровергает ваши слова о том, что "прямого одностороннего биндинга нет" — он есть, и работает по умолчанию, без всяких модификаторов.

Согласен, есть разница между v-model(двусторонний бинд) и :value(односторонний). И может не совсем удачный пример именно с инпутом. Но это не отменяет того, что есть компоненты, с которыми такое не пройдет без подавления внутренних ивентов. Например, jsfiddle.net/4zufmzvf, в этом примере прибинденное проперти меняется только непосредственно вручную, с подавлением ивентов, и в данном случаи уже без разницы это :value или v-model.

И опять-таки, никакой .sync вам не потребовался. И даже e.stopPropagation() не потребовалось… Тогда о чем вообще ваш пост?


PS все три варианта: https://jsfiddle.net/4zufmzvf/1/

будет написать этот update:foo самому

Согласен полностью, но речь идет об уже написанных не мной компонентах, со своим поведением update, и когда на уровне компонента мы узнаем об нем, то все уже свершилось, а нам надо проникнуть на самое начало этого события. А native позволяет мне перехватить событие в его самом начале, благодаря чему я могу им управлять так как мне надо, а не как реализовано внутри компонента.
Зарегистрируйтесь на Хабре , чтобы оставить комментарий

Публикации

Истории