СоХабр закрыт.

С 13.05.2019 изменения постов больше не отслеживаются, и новые посты не сохраняются.

H Сравнение Vue.js с Angular и React, и почему Vue выигрывает в черновиках

Как говорил М.Т. Калашников: «Просто» сделать в 1000 раз сложнее, чем «сложно». Веб-индустрии понадобилось более половины десятилетия, чтобы прийти от фреймворков-монстров к простой и элегантной конструкции. В IT простота это не только сэкономленные часы работы, а ещё и прозрачная архитектура, выливающаяся в понятный код, меньшее число багов, более быстрое внесение изменений и много других приятных вещей.

В этой статье я проведу сравнение Vue.js с двумя наиболее популярными на данный момент фреймворками: Angular и React. Vue.js намного моложе, поэтому разговор будет прежде всего о нём, об Angular и React грамотные разработчики и так знают. Я бы не начинал этот разговор, если бы Vue не предлагал чего-то действительно стоящего. К счастью это так, и я утверждаю, что в большинстве случаев Vue.js может серьёзно снизить сложность ваших программ, сделать код более лаконичным и выразительным, а отладку — короче и проще. Подробности под катом. Поехали!

Если совсем кратко, то Vue.js — невероятно ненавязчивый фреймворк. Если Angular и React заставляют вас установить целый зоопарк зависимостей, то Vue в минимальной конфигурации не просит от вас абсолютно ничего, кроме собственного js-файла. За это он даёт custom controls, data binding, кастомные директивы и, фактически, все востребованные фишки основных фреймворков. Пример ненавязчивости:

Как выглядит простейшая программа на Vue


Достаточно просто подключить библиотеку, создать контейнер и вызвать конструктор, всё как в старом добром Angular 1, только без его тормозов:

<div id="app">{{ message }}</div>

<script src="https://unpkg.com/vue"></script>
<script>
  new Vue({
    el: '#app',
    data: {
      message: 'Hello Vue!'
    }
  })
</script>

Это действительно весь код, который вам нужен, это не шутка. Вы можете прямо сейчас скопировать его в редактор, сохранить как something.html и он будет работать. Без плясок с бубном, dependency hell и прочих артефактов современности. Не буду рассказывать как то же самое делается в React или Angular 2+. Про то, как вытащить JSX из React или как писать без TypeScript на Angular 2+ можно написать целую статью.

Почему бы не оставить всё как есть
Чем плох TypeScript? Хотя бы тем, что я его не заказывал. В 2005-м году мы боролись за каждый килобайт веса страницы, а сейчас сайты весят по 15 мегабайт и, как будто бы, так и нужно, но это неуважение к пользователю. Я не говорю, что в этом виноват TypeScript, или JSX, или 100500 других побочных технологий, но я хочу сам выбирать, что использовать, а что нет. И чтобы не пришлось платить за этот выбор часами на stackoverflow.

Что касается конкатенации и минификации кода, то для Vue доступно много решений с готовыми сборщиками на том же yeomen (например github.com/birdgg/generator-vuejs), так же как и для React или Angular. Разница в том, что у вас есть право выбора, использовать их, не использовать, или самому создать сборщик под особенности конкретного проекта.

Custom Controls


Распространённый сценарий развития большинства веб-приложений — увеличение плотности функционала:

  • у вас была обычная кнопка, а стала кнопка со индикатором состояния запроса
  • была обычная таблица, а стала таблица с сортировкой и фильтрами
  • было обычное меню, а стало меню с многократной вложенностью

Если такие компоненты встречаются в приложении один раз — ничего страшного, но чаще бывает, что они раскиданы по разным страницам и в большом количестве. Без custom control такие задачи решаются через боль, мучения и большие затраты времени, с custom controls это делается быстрее в несколько раз. Если вы не сталкивались с такой проблемой — значит у вас не было более-менее серьёзных проектов. Custom controls — это абсолютно must have в современном frontend-программировании. В Angular 1 custom controls отсутствовали (если не считать директивы, которые изначально предназначались совсем для других вещей). В Angular 2+ и React они есть, но достаются довольно дорого. Синтаксис Vue.js очень похож на Angular 2+, но без его ограничений. Немного модифицируем код, представленный выше:

<div id="app">
  <ol>
    <todo-item v-for="item in list" :todo="item"></todo-item>
  </ol>
</div>

<script src="https://unpkg.com/vue"></script>
<script>
  Vue.component('todo-item', {
    props: ['todo'],
    template: '<li>{{ todo }}</li>'
  });
  
  new Vue({
    el: '#app',
    data: {
      list: ['first item', 'second item']
    }
  });
</script>

Получилось чуть подлиннее, но у нас здесь custom controls. Custom controls в 20 строчках кода, Карл! При этом сам компонент занял всего 4 строчки. Что это значит на практике: что вы можете делить свой код на компоненты настолько мелко, насколько вам хочется, с минимальными издержками. Если в React создание отдельного компонента — целая история, с завязкой, кульминацией и развязкой, то в Vue это просто несколько секунд. И дело не в этих секундах, а в том, что с большим количеством компонентов у вас будут слабее зависимости и меньше багов.

Это синтетический пример компонента, но в реальных Vue.js раскрывает себя ещё лучше. Мы можем, например:

  • вынести весь код компонента в отдельный *.vue файл, включая html, css и javascript
  • использовать css-препроцессоры прямо в коде файле компонента, просто указав lang=«scss» или другое
  • использовать любые глобальные объекты или получать объекты через import (в React, кажется, на это есть ограничения)
  • использовать компоненты только внутри других определённых компонентов, без объявления в глобальной области видимости. Использовать компонент под другим именем, без изменения самого компонента (удобно в случае коллизии имён сторонних компонентов)

и многое другое. Для большинства этих функций нужно подключать сборщик (в документации описан webpack), однако вам дают выбор, использовать Vue на 10%, 50% или на все 100%. Плюс, на мой взгляд, они выбрали самый стабильный и прозрачный сборщик из существующих, но вы можете поменять и его. Вообще Vue поражает своей модульностью и слабосвязанностью, архитектура просто очень хорошо продуманна, что выливается в огромное удовольствие при работе с любой его составляющей. Например:

Создание своих плагинов


Перед тем, как открыть спойлер с кодом остановитесь на минутку и подумайте, как бы вы пропатчили незнакомую библиотеку, если бы захотели добавить туда новый кастомный метод. Подумали? Теперь открывайте ответ:

Как это делается в Vue.js
  Vue.prototype.$myMethod = function (methodOptions) {
    // something logic ...
  }

Vue.prototype, Карл! Вам даже не нужно знать документацию, вы её и так знаете большую её часть на уровне подкорки. Больше никаких странных конфигов, магических свойств, которые нужно указать, чтобы всё заработало. Просто Vue.prototype и имя вашего метода, почему все фреймворки не используют это? Если хотите устанавливать плагин через Vue.use(MyPlugin), то нужно определить метод MyPlugin.install, но это, как и многое в Vue, по вашему желанию.

Общая обстановка


У меня есть большие претензии к команде Angular. Даже не побоюсь сказать, что они фактически убили Angular, создав два совершенно разных продукта и назвав их одним именем. Даже у Vue больше общего с Angular и 1 и 2, чем у этих версий между собой. Возникла огромная путаница в документации, которая ещё не скоро прекратится. Но дело даже не в этом, как гласит один из канонических принципов создания хорошего ПО: делайте программы открытыми для дополнения, и закрытыми для изменения. Подобные радикальные изменения API Angular говорят о том, что продукт изначально был создан проблемным, идеальные программы не нуждаются в изменениях (например /bin/true в linux не переписывалась с 1984 года :)). Конечно Angular это не /bin/true, но реформы — всегда признак проблем.

В чём же причина? Я думаю в том, что как React — это проект для внутренних нужд Facebook, так и Angular 2+ — это проект для внутренних нужд Google. Конкретной компании не требуется поддерживать универсальность. Зачем поддерживать ES6, если в самой компании пишут на TypeScript? Зачем отделять React от зависимостей, если внутри компании он без зависимостей не используется? Конечно пользователи просят, и иногда им идут на встречу, чтобы они совсем не отвернулись, но всё же главная задача этих проектов — не наше с вами счастье, а облегчение найма в эти компании, когда приходит новичёк и уже знает основной стек технологий. Но стек конкретной компании, пусть даже очень крутой, не может являться стандартом для всей отрасли. Отсюда все проблемы с Angular и React. Vue, насколько мне известно, напротив, создавался именно для сообщества, поэтому получился модульным, универсальным, легко адаптируемым под нужные задачи.

комментарии (397)

+16
+18 –2
rumkin ,   * (был изменён)

Нельзя сравнивать библиотеки хеловордами и туду листами. Соглашусь, что React и Angular требуют много зависимостей и тяжеловесны. Но в больших приложениях (даже начинающихся с легковесных библиотек), которые состоят из множества маленьких модулей рано или поздно наступает такой момент, когда вес страницы начинает зашкаливать из-за того, что каждая библиотека тянет за собой множество дублирующих друг друга вспомогательных библиотек (как пример одновременное подключение lodash и underscore). Это неприятно, но на данный момент неизбежно. Так, что давайте сравнивать по срезу проектов и по нескольким показателям.


Для меня главным ресурсом является время на разработку, все остальное я могу оптимизировать.

–1
+11 –12
rboots ,  
Полностью согласен, но в рамках статьи показать что-то сложнее hello world и todo затруднительно. На Vue я пару месяцев назад начал первый production-проект, и пока ощущения лучше, чем от Angular и React, которые тоже использовал в production. Вот и решил поделиться.
+9
+11 –2
rumkin ,  
в рамках статьи показать что-то сложнее hello world и todo затруднительно

С чего вы взяли?


На Vue я пару месяцев назад начал первый production-проект

Так дело не пойдет. Переименуйте тогда статью в "Почему я считаю vue лучшим фреймворком 2017" ну или как-то так.

–3
+6 –9
rboots ,  
Ну видите, у нас на простых вещах разногласия, а вы хотите, чтобы я здесь сложные описывал. У меня не хватает таланта. Напишите свою статью про то, как надо писать статьи)
+2
+4 –2
antonksa ,  

Вам говорят о том, что вы поймали хайп.
Мы за вас конечно рады, но вам предложили написать, что это ВАШЕ СУГУБО ЛИЧНОЕ МНЕНИЕ, а не безаппеляционное заявление, как сейчас выглядит заголовок.

0
+5 –5
rboots ,  
Все оценочные утверждения это лишь мнения. Или вы думаете, что где то на планете есть великий мудрец, объявляющий «А на этот год лучший фреймворк такой-то». Естественно это мнение, странно, что можно решить иначе. К этому мнению я привожу список агрументов, так сказать, доказательств теоремы. Ваше право указать на неверные тезисы или согласиться.
+2
rumkin ,   * (был изменён)

Все оценочные суждения должны быть помечены как таковые, иначе подтверждены фактами или раскрыты. Лучший по мнению экспертов, по показателям скорость/качество, по мнению моей мамы. По-умолчанию подразумевается лучший вообще, а не "по моему мнению". Иначе у вас получается кликбейт или, по-русски, желтый заголовок.


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

+7
+8 –1
raveclassic ,  
пару месяцев

Вы что, серьезно?


Angular и React, которые тоже

Тоже пару месяцев?

0
+2 –2
rboots ,  
С учётом того, что Vue начал набирать реальную популярность только в 2016 и многие до сих пор боятся использовать его в production — абсолютно серьёзно. Сколько вам надо, 5 лет? На Angular наверное наберётся, но Vue в принципе моложе. Плюс документация осваивается за пару вечеров, а косяки которые не всплыли за первые два месяца, вряд ли могут иметь критическое значение, всё серьёзное проявляется очень рано.
+7
staticlab ,  

Как раз архитектурные недостатки начинают проявляться на довольно сложных приложениях, которые пишутся дольше, чем пару месяцев.

–2
rboots ,  
Vue придумал очень мало нового, всё кроме слотов уже было в том или ином фреймворке, только в менее удобном виде, поэтому архитектурные вопросы прекрасно оцениваются. Просто посмотрите из каких частей он состоит.
0
staticlab ,  

Ниже я уже показал, что концепция слотов не так уж и уникальна, если то же самое можно и в Реакте повторить.


Что касается архитектуры, то это вопрос не множества возможностей фреймворка, а, скорее, их взаимодействия между собой и с бизнес-логикой.

+1
TimTowdy ,  
Концепция слотов не придумана Vue. Достоинство Vue как раз в том, что вместо придумывания своих велосипедов они взяли за основу уже существующую спецификацию W3C: http://w3c.github.io/webcomponents/spec/shadow/#shadow-tree-slots
+1
staticlab ,  

А в чём, собственно, достоинство?

+5
ncix ,  

Никому не нужен новый инструмент, который нужно осваивать дольше пары недель. Или в котором через два(!) месяца чувствуешь себя новичком. Серьезно.

+2
mariner ,   * (был изменён)
с Vue вам понадобится два-три дня ;) там банально нет столько функционала, что бы изучать.
0
+1 –1
TheShock ,  
но в рамках статьи показать что-то сложнее hello world и todo затруднительно

Может проблема во фреймворке? Или еще в чем-то?

Я в своих статьях описывал даже создание небольших игрушек. Конечно, это не очередной хелло-ворлд, но ничего особо затруднительного не вижу. Если есть знания и материал, то вполне себе описывается.
0
+1 –1
Areso ,  
Написал игру на чистом JS, причем используя очень старые вещи. Ничего, работает)
Даже jQuery пока нет в зависимостях.
+1
+2 –1
TheShock ,  
Ну и где статья? Мы ведь о статьях говорим, а не о игрушках?
В рамках статьи о Vue сложно написать что-то сложнее Hello World, но в рамках статьи о других фреймворках и даже без фреймворков пишут вещи, которые значительно сложнее.
Следовательно может быть проблема во фреймворке, что с ростом сложности читаемость падает слишком быстро и для статьи такой код не подходит.
–1
Areso ,   * (был изменён)
Вы всерьез хотите увидеть статью об очередной ферме на JS, написанной любителем? Я ведь зарабатываю деньги совсем другими вещами. Причем написанной без новых, модных фич JS? К тому же код демонстрирует значительное количество непоследовательных решений, которые точно нельзя назвать best practice (к примеру, рендер в Canvas, а поверх просто расположение картинки со своими функциями или анимации, чтобы не мучаться с разделкой анимации и вставкой анимации покадрово в Canvas). Т.е. мне непонятно, чему бы я мог научить других людей такой статьей, а пиарить поделку-на-коленке тоже я смысла особого не вижу.

Так-то написать можно, был бы положительный выхлоп.
+4
+7 –3
Tynnopet ,  
Писал по небольшому компоненту, с большим количеством перерисовок на react и vue. Из-за встроенного observable и computed свойств vue обошел реакт в 3 раза по фпс. Помимо этого кода было на порядок меньше, из-за тех-же computed свойств. Как я ни старался react по lifecycle хукам оптимизировать — vue без оптимизаций был быстрее.
+2
+3 –1
Reon ,  
Откуда у вас такая информация, что именно по этим причинам?
0
RubaXa ,  
Из DevTools например

+1
Tynnopet ,  
Достаточно посмотреть на области перерисовки при одной архитектуре компонента
React
image

Vue
image
0
justboris ,  

Не может такого быть, чтобы Реакт не смог сделать перерисовку только изменившихся частей.


Покажите код, и может быть, я укажу, что было там не так.

0
vintage ,  

Может. Там довольно дубовый реконцилятор. Достаточно перенести элемент в другого родителя и он сделает полную его перерисовку.

0
justboris ,  

А зачем вам переносить элемент в другого родителя?
Сколько разных интерфейсов ни писал, но этого делать не пришлось.

0
vintage ,  

Дрегендроп, фуллскрин, да и просто динамический лейаут.

+1
justboris ,  

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


Про фуллскрин и динамический лейаут я не понял пример, расскажите подробнее

+1
vintage ,  

Достаточно перетащить тяжёлую панель из левого дока в правый.


Листаете ленту, наткнулись на видос, решили тут же глянуть о чём он, заинтересовало, решили открыть его в попапе, чтобы покрупнее.


Смотрели список задач плоским списком, а потом решили сгруппировать их по ответственному.

0
Reon ,  
Vue возможно быстрее, так как использует snabbdom в качестве виртуального дома.
0
mariner ,  
использую с октября прошлого года. скорость разработки высокая, нехватка функционала (например, http клиент), быстро решается интеграцией того же axios через плагин к Vue. в общем, все круто там. не хочется возращаться к ангулару или реакту.

экосистема развивается — https://github.com/vuejs/awesome-vue
и да, single file components это просто бомба!
0
franzose ,  

http-клиент есть: https://github.com/pagekit/vue-resource

+1
mariner ,  

Его больше не рекомендуют использовать (в блоге разрабов вью). Советуют axios.

0
franzose ,  

Хм, спасибо, не знал. Надо будет в своём репозитории (https://github.com/franzose/symfony-ddd-wishlist) переделать на axios тогда, чтобы не вводить людей в заблуждение.

0
s256 ,  
По какой причине? Для простых вещей вроде довольно удобный
0
Fragster ,  
По той, что есть axios. Это официальная позиция :)
0
franzose ,  

Хотя это тоже отдельный плагин)

+7
+9 –2
j_wayne ,   * (был изменён)
Vue мне хорошо подошел в проекте, т.к. уже есть фронтенд на jquery, целиком переписывать я не хочу, но с поддержкой уже есть проблемы и для новых фич нужна реактивность.
Vue я могу применять точечно, для новых фич и постепенно переписывая старые.
«Чистые» Elm и React/Redux не осилил, слишком много обычных сторонних либ.
Vue не мешает «срезать углы» и сделать грязный хак, если надо.

P.S. Также, я вынужденный фулл-стек программист и изучать большие фреймворки нет ресурсов.
0
rboots ,  
Так же не мешает вместо грязного хака сделать чистое архитектурное решение, например делегировать часть функционала другому модулю/библиотеке, который справляется с ней лучше. По мне так это плюс, что Vue «не мешает», а как пользоваться полученной свободой — уже ответственность программиста.
0
friday ,  

Вот так всегда и бывает: сначала срезают углы и делают грязные хаки, а потом жалуются на проблемы с поддержкой.

+1
j_wayne ,  
А проблемы с поддержкой уже были и более серьезные — легаси лапшекод на jquery.
Я пробовал внедрить ограниченно (в рамках новой фичи ) react/redux, потом Elm.
Концептуально красиво, безусловно. Особенно Elm.
Но у меня просто нет ресурсов взять и переписать все эти уже используемые календари, чарты, пикеры и прочие сторонние библиотеки на redux/elm.
В частности, jquery draggable/droppable. На redux я еще худо бедно сделал, вроде даже и в рамках концепции, но выглядело в коде это не ахти.
На Elm drag/drop я просто не осилил (был глючный пример для старой версии, но как раз вышла новая где этот API прибили). Я думаю, что в принципе это возможно, но лично у меня заняло слишком много времени и непонятно, зачем такие сложности. Done is better than perfect. Это не значит, что к совершенству не надо стремиться. Но иногда компромисс неизбежен.
+19
+21 –2
justboris ,   * (был изменён)
Если в React создание отдельного компонента — целая история, в завязкой, кульминацией и развязкой

Если и история, то очень короткая:


function MyReactComponent() {   // завязка
  return React.createElement('h1', 'Hello from my React component') // кульминация
} // развязка

ReactDOM.render(React.createElement(MyReactComponent), document.getElementById('app'));
–8
+3 –11
rboots ,   * (был изменён)
Это со статическим содержанием, а попробуйте хотя бы аналог компонента из примера, с одним свойством, отображаемым в содержании. Сколько строк получится?
0
+1 –1
justboris ,  

Не больше чем в аналогичном todo-list на Vue


var h = React.createElement;

function TodoItem(props) {
  return h('li', {}, props.text)
}

function TodoList(props) { 
  return h('ol', {}, props.items.map(function(item) {
    return h(TodoItem, {text: item});
  }));
}

var items = ['first item', 'second item'];

ReactDOM.render(React.createElement(TodoList, {items: items}), document.getElementById('app'));

И вот работающий JSFiddle

+3
+4 –1
dom1n1k ,  
Гораздо больше, если так можно выразиться, синтаксического шума.
0
justboris ,  

Согласен, причесал немножко: https://jsfiddle.net/nwtmq49k/1/ Стало лучше?


Ну и не стоит забывать о JSX. Если проект намечается большим, то тут уже можно и JSX подключить и писать верстку нормально.

–6
rboots ,  
Неплохо, но хитрость с map обернётся слабой выразительностью кода. И в целом javascript получилось не меньше, в изначальном примере его всего 11 строчек javascript, остальное — html, импорт библиотеки, теги script и т.п… Если сравнивать Fiddle, то вот: https://jsfiddle.net/km8jug2f/2/
В целом соглашусь, что практически равные результаты, но Vue всё же читается и пишется проще.
+4
+5 –1
raveclassic ,  
но хитрость с map

Почему хитрость? Обычное преобразование


слабой выразительностью кода

Почему? Разве стандартная языковая конструкция хуже чем кастомный dsl?


11 строчек javascript, остальное — html, импорт библиотеки, теги script и т.п…

Какая разница чего сколько, если все — исходники?

+6
+7 –1
justboris ,  

Ну вот, видите, не так уж страшно на React писать. А в статье много необоснованного хейта


Angular и React заставляют вас установить целый зоопарк зависимостей

плясок с бубном, dependency hell и прочих артефактов современности

React создание отдельного компонента — целая история, в завязкой, кульминацией и развязкой

Не надо так.

–1
+1 –2
rboots ,   * (был изменён)
Официальная документация просит зоопарк устанавливать. Даже самый простой вариант с single html запрашивает babel и делает преобразование из jsx, что увеличивает время отрисовки страницы, по моим замерам, до 1.5 секунды. Кто же знал, что вы познали Дао React и можете написать Hello world лучше, чем основатели React. К вам претензий нет, к ним — есть, в том числе за документацию.
0
raveclassic ,  
до 1.5 секунды

Так вы в рантайме его зачем гоняете?

–6
+1 –7
rboots ,  
Это не я, это официальная документация) Упаковка это хорошо, но я хочу иметь выбор. Почти любой фреймворк на чистом JavaScript прекрасно работает и в рантайме, а babel и typescript — нет. При этом преимущества такой надстройки абсолютно не очевидны, а минусы на ладони.
+1
Alex_ME ,  

Чтобы использовать более удобные вещи, которые еще не поддерживаются всеми браузерами (es6, 7, что там еще), совсем не поддерживаются браузерами (typescript, jsx, sass/less).

–4
rboots ,  
Они ещё остались? На мой взгляд async await была последней, если только вы программируете на для гос учреждений, не обновляющих браузеры.
0
staticlab ,  

Object rest/spread, например

–5
rboots ,  
1. конструкция очень спорная и может породить кучу багов
2. если очень хочется — можно использовать apply
3. проблемы с параметрами как таковой нет. С асинхронностью есть, с разбиентием на компоненты — есть, с параметрами — нет
+5
staticlab ,  

Простите, но что вы несёте?

0
raveclassic ,  

Банально es6-модули

0
rboots ,  
Есть сотни инструментов для этого, не тянущих за собой столько лишнего, как babel. Webpack, requirejs, ещё в 2012 мы самописные инструменты писали на 50 строчек, штука нужная, но очень простая
+2
raveclassic ,  

Вы какой-то странный хейтер бабеля. То есть дополнительные инструменты в проект тащить ок, но только не бабель?

0
staticlab ,  

Очевидно же, потому что бабелем можно транспилировать JSX.

+1
Alex_ME ,  

Если уж у нас есть всякие инструменты преобразования кода


  • трансляторы less/sass
  • автопрефиксеры
  • минификация
  • модули

то какая проблема добавить еще один для трансляции js?

+1
justboris ,  

А вот и нет. По указанной вами ссылке страница с тремя опциями: Try React, Create a New App, Add React to an Existing App


Первая дает ссылку на codepen с примерно таким же контентом, как я написал в JSFiddle.


Тут скорее проблема в том, что в сообществе, в том числе и на Хабре, сложился шаблон React — это Redux, Webpack, Babel и никак иначе. Так теперь и кочует из статьи в статью.

0
rboots ,  
В примере на codepen тоже используется babel
0
staticlab ,  

И что? При транспиляции babel превратит его в такой:


ReactDOM.render(
  React.createElement('h1', null, 'Hello, world!'),
  document.getElementById('root')
);

JSX не используется в рантайме.

+8
+9 –1
andy128k ,  
Столько же

function MyReactComponent(props) {
  return React.createElement('h1', props.message || 'Hello, React!');
}

ReactDOM.render(React.createElement(MyReactComponent, {message: 'Hello, Vue!'}), document.getElementById('app'));
–16
+1 –17
rboots ,  
Неплохо, но длина строк тоже имеет значение. 221 символ против 98 в пользу Vue. Хотя это не суть, суть в простоте и удобстве.
+9
+10 –1
Alex_ME ,  

Почему не JSX?


function MyReactComponent(props)
{
    return <h1>{props.message || 'Hello, React!'}</h1>
}

ReactDOM.render(<MyReactComponent message="Hello, Vue!"/>, document.getElementById('root'));

Согласитесь, так гораздо нагляднее и компактнее, без всякого синтаксического шума, как выражались некоторые комментаторы.

+5
+6 –1
TheShock ,  
Кстати, с es6 импортами вполне можно было сделать довольно изящно на функциях без всяких синтаксических дополнений:

function MyReactComponent(props)
{
    return h1{props.message || 'Hello, React!')
}

ReactDOM.render(MyReactComponent("Hello, Vue!"), document.getElementById('root'));


Или более развернуто:

import { h1, h2, section, article, div } from "react-elems";

function MyReactComponent(props)
{
    return [
        h1{[props.message || 'Hello, React!']),
        section({ className: "abc" }, [
            h2("blabla"),
            article([
                div({ className: "xyz" }, "foobar")
            ])
        ])
    ];
}

ReactDOM.render(MyReactComponent("Hello, Vue!"), document.getElementById('root'));


В аргументах функции объект — это свойства, а массив или строка — чилдрены.
Как по мне — вполне соответствует JSX по наглядности и компактности.
+2
+4 –2
Alex_ME ,  

Не могу с Вами согласиться. Все-таки JSX — по-сути привычный всем HTML, а этот синтаксис необычен и более многословен (все эти скобки и прочее). Есть ли плюсы у такого подхода? Всегда считал JSX одной из сильных черт реакта.

+1
+2 –1
TheShock ,  
На счет многословности не соглашусь: xml в принципе более многословен за счет закрывающего тега и кучи угловых скобок. По сути для крайнего случая это:

tag({ property: value, [ item1() ] })
// vs
<tag property={value}><item /></tag>


Для самого простого:

tag(value)
// vs
<tag>{value}</tag>


И т.к. мы пишем на JS, то всем кто это пишет это настолько же привычный JS, как и HTML.

Лично мне нравится jsx, я просто описал, что такая альтернатива есть.

Из плюсов — такой подход не нужно собирать (для браузеров с es6 и nodejs), это нативный JS (слабый плюс, конечно, но все-же). Ну и код слегка короче получается. Либы, которые хотят сделать «так же легко как в реакте, но без jsx» — могут использовать именно этот подход, он не сильно отличается.
0
sshikov ,  

Ну исли этот синтаксис и необычен — то только для вас. Его полно везде, и уже давно.


Да, фактор непривычности всегда существует, но тут вы его явно преувеличиваете. Это просто javascript, если на то пошло.


Есть ли плюсы у такого подхода?

Да. Такой синтаксис лучше компонуется. Если вы генерируете свой компонент из какой-то структуры данных, то так обычно удобнее.

–1
Mox ,   * (был изменён)
Эта штука хорошо бы сработала с CoffeeScript — получился бы HAML по сути
0
Fragster ,  
ну а в vue просто используем pug
0
vintage ,  

Добавляем интерактив с пользователем и получаем куда более увлекательный сюжет.

0
lega ,  
а попробуйте хотя бы...
А вы можете сделать аналог (гибкие шаблоны в компонентах, jsfiddle) на vue для сравнения?, а то для ангуляра 2 это целая проблема.
0
rboots ,  
Что за гибкие шаблоны? Гугл не знает, по ссылкам понятный, но ничем не примечательный код. Какую задачу вы хотите решить? Может быть вам нужны слоты, они помогают сделать шаблоны гибче.
0
lega ,  
Просто вы там выше меряетесь объемом кода:
221 символ против 98 в пользу Vue
Вот вам пример где vue проиграет, так же vue тут может поиметь проблем с миксом контекстов на одном шаблоне.
0
rboots ,  
Так что за гибкие шаблоны то? И почему вы решили, что Vue обязательно проиграет?
0
lega ,  
Я вам ссылку на статью кинул, там подробнее об этом. Дак от вас стоит ждать аналога на vue? для сравнения сложности и объемов вариантов.
+1
rboots ,  
Понял, вы хотите менять шаблон компонента в зависимости от его параметров. Архитектурно это не правильный подход, так как шаблон для каждого типа компонентов компилируется один раз и сделать его динамическим — придётся платить за это тормозами, в любом фреймворке. Правильным подходом будет создать фабрику компонентов, где сгенерировать для каждого шаблона отдельный компонент со общими настройками логики. На практике же как правило достаточно того, что вам предложили в конце статьи, или внести все варианты шаблона в один и разрешить классами, или разрешить в шаблоне через if else. Код переписывать не буду — слишком много букв.
+1
raveclassic ,  

Не шаблон и не менять. Мне (и не только мне) нужен инструмент для проброса компоненту класса другого компонента для внутреннего использования в качестве параметра. Ну, проще говоря, компонент высшего порядка. TS/flow тут еще и помогает описать интерфейс этого нужного компонента.


Я не собираюсь на каждый чих лазать в базовый компонент и накручивать в нем дополнительные флаги/аттрибуты. Мне нужен должный уровень абстракции, и не один движок со статическими шаблонами мне этого не даст.

0
JSmitty ,  
Не очень вникал, но то, что вы описываете — очень похоже на механизм scoped slots во Vue.js — доступный с 2.1 версии.
0
raveclassic ,  

Спасибо за наводку. Подходит скорей dynamic components из ссылки.

+5
s256 ,  
Что касается custom controls я бы упомянул одну из мощнейших, на мой взгял фич Vue — слоты. Они привносят наследование в шаблоны, и в идеале я могу переопределять разметку чужих компонентов не затрагивая логику!
+5
staticlab ,  

В реакте прямой аналог неименованных слотов — это this.props.children, а именованных — другие кастомные пропы:


Vue

app-layout:


<div class="container">
  <header>
    <slot name="header"></slot>
  </header>
  <main>
    <slot></slot>
  </main>
  <footer>
    <slot name="footer"></slot>
  </footer>
</div>

parent-container:


<app-layout>
  <h1 slot="header">Here might be a page title</h1>
  <p>A paragraph for the main content.</p>
  <p>And another one.</p>
  <p slot="footer">Here's some contact info</p>
</app-layout>

Результат:


<div class="container">
  <header>
    <h1>Here might be a page title</h1>
  </header>
  <main>
    <p>A paragraph for the main content.</p>
    <p>And another one.</p>
  </main>
  <footer>
    <p>Here's some contact info</p>
  </footer>
</div>

React
const AppLayout = ({ header, footer, children }) => (
  <div class="container">
    <header>
      { header }
    </header>
    <main>
      { children }
    </main>
    <footer>
      { footer }
    </footer>
  </div>
);

const ParentContainer = ({}) => (
  <AppLayout
    header={ <h1>Here might be a page title</h1> }
    footer={ <p>Here's some contact info</p> }
  >
    <p>A paragraph for the main content.</p>
    <p>And another one.</p>
  </AppLayout>
);

Ну а аналогом scoped slots может быть передача в компонент функций рендеринга.

0
+2 –2
indestructable ,  

Vue использует глобальный объект для регистрации компонентов.


В результате переименование — проблема, появляется зависимость от порядка объединения файлов, ну и узнать, где какой компонент, можно только поиском.


Реакт, при всех его расписываемых недостатках, имеет одно большое преимущество — это джаваскрипт, а не кастомный язык шаблонов. Причем джаваскрипт современный, использующий новые возможности, а не борющийся с ними, как первый Ангуляр.

+9
rboots ,  
В любом компоненте можно определить свой локальный список components, дать им любые псевдонимы и не зависеть от имён компонентов (самый правильный пусть).

React безусловно крут, иначе его не было бы в этом сравнении, но JSX это не JavaScript. На JavaScript без JSX можно, но тогда уж проще на VanillaJS, ещё быстрее будет. А шаблоны удобны тем, что их можно отдать верстальщику и снять с разработчиков 50% рутины, там шрифты не те, тут цвет и прочие не относящиеся к программированию вещи.
0
indestructable ,  
В любом компоненте можно определить свой локальный список components, дать им любые псевдонимы и не зависеть от имён компонентов (самый правильный пусть).

Я не использовал Vue, не могли бы вы показать коротенький пример или ссылку на доку?
Я так понимаю, что в файлах определяется только конфигурация компонента (второй параметр Vue.component), а регистрируются дочерние компоненты прямо в родительском?


React безусловно крут, иначе его не было бы в этом сравнении, но JSX это не JavaScript. На JavaScript без JSX можно, но тогда уж проще на VanillaJS, ещё быстрее будет.

React — это далеко не только JSX, очевидно же. И JSX — это 10% его функционала максимум, просто самое запоминающееся.

–1
avdept ,  
Писать шаблоны в jsx ничем не сложнее обычного хтмл
+1
TimTowdy ,  
Писать — да. Но не читать.
Посмотрите на PHP — это язык-шаблонизатор. Но почему-то в подавляющем большинстве случаев в нем используют сторонние шаблонизаторы. Как вы думаете, почему?
0
+1 –1
VolCh ,  
Прежде всего для изоляции кода шаблона от остального кода приложения с основной целью запретить или сильно усложнить мутации окружения шаблона из шаблона.
0
avdept ,   * (был изменён)
Не одним php едины. Я не пишу на пыхе, и не знаю как там все обстоит. Но я знаю ситуацию в других веб ориентированых ЯП — и там используют кому что нравится, ибо отличия только в синтаксисе.
А вот в чем проблема читать jsx я не пойму. Или религия не позволяет открывать файлы в которых намешана логика и вьюха? Да jsx это то, чего на протяжении десятилетий старались избегать в других ЯП\фреймворках. Но суть реактивного подхода — «каждая запятая» это отдельный компонент, и таким образом ваш компонент не должен быть больше чем пара десятков строк кода.
+1
TimTowdy ,  
Я тоже на PHP никогда не писал, привел просто для примера. В подавляющем большинстве шаблонизаторов используется свой DSL, а прямой вызов кода на GPL языке либо невозможен, либо не приветствуется.

Вы, похоже, не понимаете, откуда взялся JSX. Это не просто очередной шаблонизатор. И не просто смесь логики и вьюхи.
Для борьбы с нарастающей сложностью UI, ребята из FB решили реализовать идею «UI as function of state». Чтоб это не тормозило — использовали VirtualDOM. И все вроде бы хорошо: и сложность уменьшили, и работает быстро. Но оказалось что у такого подхода есть недосткток: разметка куда-то пропадает. Есть только код, генерирующий разметку. И, как вы понимаете, когда у вас возникает задача связанная с версткой, отсутствие разметки очень сильно сказывается на продуктивности. Для этого и придумали JSX — расширение JS, позволяющее использовать XML-подобный синтаксис написания JS-VirtualDOM кода. Идея, на то время, просто отличная.

И, Vue, если вы не в курсе, делает абсолютно то же самое. Точно также транслирует код шаблона в VirtualDOM вызовы. Но делает это более элегантно, в том числе не позволяя размазывать разметку по разным кускам компонента. Эта разница во Vue и React связана с их историей. Во Vue сначала был дизайн, а VirtualDOM лишь потом оказался деталью реализации. React же с самого начала был твердо завязан на VirtualDOM, и JSX — это просто костыль, созданный для облегчения работы с ним. На 2013 год — костыль просто великолепный. Но уже 2017 на дворе.

А про «реактивный подход» вы какую-то глупость написали. Он вообще-то ни к React, ни к компонентам не имеет никакого отношения.
0
avdept ,  
Мой посыл был что писать шаблоны в jsx ничем не сложнее чем на хтмл, и довода обратно я не увидел.

PS React — это и есть реализация паттерна реактивного программирования
+2
vintage ,  
React — это и есть реализация паттерна реактивного программирования

Я бы так не сказал.

–7
+2 –9
vasIvas ,  
angular стал знаменитым благодаря архитектуре.
react стала знаменитым благодаря агрессивному маркетингу.
vue стал знаменитой благодаря laravel.

И независимо от того, кто и что любит и у кого какое мнение, пока лидирует angular.
Да и выбор, на мой взгляд, обуславливается уровнем.
+10
rboots ,  
Никогда не пользовался laravel. Vue стал знаменитым, потому что делает те же вещи проще и быстрее
+8
Apathetic ,  

Лидирует в чем?

–6
+1 –7
vasIvas ,   * (был изменён)
В моем понимании он лидирует в нише, которой ещё только предстоит зародится. Он относительно молод, но на нем уже очень много приложений написано. Сам google на нем тоже пишет https://www.madewithangular.com/categories/google

А когда я слышу о его сравнении, то в голову приходит сравнить уровень авто bmw и ваз по количеству экземпляров в России. Это Вы об таком сравнении меня спрашиваете? Или Вы хотите знать, в чью сторону посмотрят пришедшие из java или c# программисты? Или Вы хотите сравнить по скорости разработки приложения за 10 т.р. на fl.ru с приложениями google? Или может с десктоп приложениями сравнивать jQ?
+3
justboris ,  
он лидирует в нише, которой ещё только предстоит зародится

Очень интересно рассказываете. И что же это за ниша?

+3
raveclassic ,  

Ух ты, назревает что-то интересненькое!

+3
Apathetic ,  

Ангуляр относительно молод? Относительно чего? GWT?) И да, странно, что google пишет на angular, они же его создали)


Вы перечислили в своем исходном комментарии три инструмента: ангуляр, реакт, вью. И сообщили, что ангуляр лидирует. При чем тут jquery? При чем тут c#? Я задал конкретный вопрос — в чем ангуляр-то лидирует? В популярности? В количестве написанных приложений? В количестве разработчиков, желающих с ним продолжать работать? Приведите статистику, пожалуйста.

+1
teux ,  

Ангуляр 1 лидирует в силу древности. Вряд ли на нем начинают много новых проектов
Angular — 9.4%
React — 1,8%
Vuy 0,3% подрастает

0
+1 –1
YemSalat ,  
angular стал знаменитым благодаря архитектуре

Изначально плохо продуманной архитектуре и маркетингу со стороны Гугла

react стала знаменитым благодаря агрессивному маркетингу.

Скорее как альтернатива Ангуляру и на том что «это просто вьюха» (т.е. гораздоо более «легкий» фрэймворк)

vue стал знаменитой благодаря laravel

На пыхе не пишу, про Ларавел знаю только название.
Vue выехал на разрабах которым нужен был легкий (во всех смыслах) фреймворк, плюс на идее фронт-энд фрэймворка без патронажа крупной организации

И независимо от того, кто и что любит и у кого какое мнение, пока лидирует angular.

В каком смысле «лидирует»?
+3
grimalschi ,  
Vue.js — это песня. Делаю проект с использованием Hot Module Reload — невероятно удобно.

Радует, что есть Vuex, и инструменты для его отладки, встраиваемые в DevTools.
0
raveclassic ,  
Hot Module Reload

HMR и в react есть.


Радует, что есть Vuex, и инструменты для его отладки, встраиваемые в DevTools.

dev-tools и для react/redux есть


Расскажите лучше, чем действительно больше нравится

0
+1 –1
grimalschi ,  
Single File Components, например.
Позволяет в 1 файле хранить HTML, JS и CSS компонента.

Вот так это выглядит
image
+4
raveclassic ,  

Забавно слышать, как то, от чего все раньше плевались ядом на старте Реакта, теперь приводят как преимущество.


Single File Components с самого начала пропагандировались в Реакте: html/css/js — все в одном флаконе. Только на одном языке (js) со всей вытекающей мощью.

–1
grimalschi ,  
JSX слабоват, но это дел вкуса.

А CSS предлагается в inline-style описывать всегда?
+3
raveclassic ,  
JSX слабоват

Чем же?


А CSS предлагается в inline-style описывать всегда?

Уже полно инструментов, которые автоматом экстрактят стили в файл.

–2
+1 –3
grimalschi ,  
Чем же?

Условиями. Какой вариант читается проще?

Vue/Angular/что-угодно:
<div v-if="condition">...</div>

React:
{ condition && <div>...</div> }


Когда таких конструкций становится много, шаблон читается сложнее.

Уже полно инструментов, которые автоматом экстрактят стили в файл.

С HMR оно все работает?
+2
raveclassic ,  
Когда таких конструкций становится много, шаблон читается сложнее

Ну по мне языковая конструкция воспринимается проще, чем сторонний dsl. Плюс, когда таких конструкций становится много, шаблон бьется на вспомогательные функции.


С HMR оно все работает?

Прекрасно работает. Даже с SSR и critical css.

0
grimalschi ,  
Ну и ладно.

Если бы не React не было бы snabbdom, а он сейчас лежит в основе Vue.js.

Что на счет Inferno.js? В репозиторие цитируют, что один из разработчиков ядра React писал следующее:

Inferno 1.0 is really well written. It's how I would've rewritten React. I'd recommend reading its source to learn.


Но Vue все-таки милее и приятнее. Это дело выбора, сами понимаете. Я с ним еще с 0.7 версии, уже несколько лет.

React у меня не получилось запустить с Redux, HRM, DevTools. Было ощущение, что пазл собираю, тогда как в Vue все части четко подогнаны друг под друга.
+1
raveclassic ,  
Что на счет Inferno.js?

Одно время засматривался, но потом взял себя в руки. Все-таки "React-like", а совместимость и поддерживаемость важнее, в продакшн не возьмешь.


не получилось запустить с Redux, HRM, DevTools

Ну чего уж лукавить, для хот-реплейса компонентов и редьюсеров там действительно поколдовать надо. Но можно начать с create-react-app, потом сюда или сразу сюда

0
grimalschi ,  
Спасибо за ссылки.
–2
YemSalat ,  
React:
condition &&  ... 

Когда таких конструкций становится много, шаблон читается сложнее.

Кто вам мешает писать по-человечески?
if (condition) ...

На вьюхи Реакта надо смотреть как на обычный JS. Если вы такие конструкции в обычном коде будете выдавать — на вас будут косо смотреть, в шаблонах то же самое.
+2
+3 –1
TheShock ,  
В функциональном ретурне ИФ не вставится.

return (
  <div>
    <First />
    {second && <Second />}
    <Third />
  </div>
);
+2
vintage ,  

Вставится:


return (
  <div>
    <First />
    { (()=> { if( second ) return <Second /> })() }
    <Third />
  </div>
);

Но самый тру вэй — это, конечно, подключить модуль composable-js:


import If from 'composable-js'
return (
  <div>
    <First />
      { If( ()=> second , ()=> <Second /> ) }
      </If>
    <Third />
  </div>
);
0
+1 –1
TheShock ,   * (был изменён)
И станет еще более нечитабельно) Я простые условия допускаю именно такие ({second && <Second />}), а что-то последнее когда комбинировать нужно, то просто выношу в метод

class Foo extends React.Component {

  renderSecond () {
    if (xA) return <SecondA />;
    if (xB) return <SecondB />;
    return null;
  }

  render () {
    return (
      <div>
        <First />
        {this.renderSecond()}
        <Third />
      </div>
    );
  }
}
+2
vintage ,   * (был изменён)

А когда JSX разбивается на маленькие кусочки, то он теряет последние остатки смысла:


renderSecond () {
    if (xA) return <SecondA />;
    if (xB) return <SecondB />;
    return null;
}

renderSecond () {
    if (xA) return SecondA();
    if (xB) return SecondB();
    return null;
}
0
raveclassic ,   * (был изменён)

Если перестать воспринимать JSX как HTML, то окажется, что XML-нотация — просто способ инстанцирования компонентов. И способ работы с SecondA будет варьироваться в зависимости от того, что она возвращает. Если компонент — JSX, если инстанс — return.

0
vintage ,  

Так зачем нам несколько способов делать одно и то же?

0
raveclassic ,  

В смысле? Функция и ее результат — не одно и то же. Класс и его инстанс — тоже не одно и то же. Другое дело, что new или просто вызов функции тут не спасают, нужен вызов createElement.

0
vintage ,  

Я привёл два кода — они полностью равнозначны.

0
YemSalat ,  
У вас некорректный второй пример, должно быть:
return second();

function second () {
  return (xA) ? <SecondA /> : <SecondB />;
}
0
vintage ,  
function second () {
  return (xA) ? SecondA() : SecondB();
}
0
raveclassic ,  

Этот трюк сработает только, если SecondA и SecondB — SFC.

0
vintage ,   * (был изменён)

С классами его тоже не трудно подружить.

0
raveclassic ,  

И как же?


Вы не подумайте, меня самого xml бесит

0
vintage ,   * (был изменён)

Что-то типа:


class Profile extends VirtualNode {
    get state() {
        return GlobalStore.get( this.id )
    }
    set state( next ) {
        return GlobalStore.set( this.id , { ... this.state , ... next } )
    }
    onchange( event ) {
        this.state = { name : event.target.value }
    }
    get children() {
        return [
            Title({ title : 'User profile' }) ,
            new Input({
                value : this.state.name ,
                oninput : event => this.onchange( event )
            }) ,
        ]
    }
}
0
raveclassic ,  

Интересно. А зачем стейт держать в GlobalStore?

0
vintage ,  

Чтобы он не сбрасывался при каждом создании экземпляра.

0
raveclassic ,  

Вот сейчас я подвис.


Стейт же локален для компонента. Это какой-то конкретный случай или вы всегда так делаете?

0
vintage ,  

Это пример как можно сделать без React.createElement. При каждом рендеринге создаются новые экземпляры компонента. Если состояние хранить локально, то оно будет теряться, вместе со старыми экземплярами.

0
raveclassic ,  

И зачем тогда классы? Состояние сбоку можно доставать и из SFC

0
vintage ,  

Можно, но не удобно. А с классами — отнаследовался и работаешь с this.state не парясь о том, где его хранить.

+2
TimTowdy ,  
Вот в этом и беда JSX. Легко писать, трудно читать.
Рано или поздно разметка расплывается по коду. Становится невозможным окинуть взглядом кусок файла и понять, а что же там отрендерится. Потому что внутри JSX у вас неизбежно появляются методы которые возвращают JSX, да еще и с условиями внутри.
0
+1 –1
raveclassic ,  

Казалось бы и в чем проблема? Отрендерится то, что вы вернете из render или из SFC-функции. Вся мощь языка в ваших руках. Полный контроль без выкрутасов с DSL.

0
+1 –1
TimTowdy ,  
Я вам про читаемость, а вы мне про мощь языка и контроль :)
Это зачастую противоположные вещи. Когда у вас есть четко определенная доменная область (а разметка таковой является), от мощи языка нужно избавляться.
SQL, например, потому и популярен, что вместо «мощи» языка общего назначения позволяет писать запрос на более ясном, лаконичном и читаемом языке.

Что происходит в голове у программиста (и не дай бог вместо программиста будет верстальщик/дизайнер), который пытается понять, а что же будет в итоговой разметке?
class Foo extends React.Component {

  renderSecond () {
    if (xA) return <SecondA />;
    if (xB) return <SecondB />;
    return null;
  }
  // ...
  // еще 5 экранов кода
  // ...
  render () {
    return (
      <div>
        <First />
        {this.renderSecond()}
        <Third />
      </div>
    );
  }
}

Ищем render(), читаем выражение которое он возвращает… Оппа, вызов метода — сохраняем прочитанную часть шаблона в «мозговой стэк», скроллим до renderSecond() читаем его, вычисляем, прыгаем назад по стэку, читаем дальше…

А если у вас там такое выражение?
{ this.shouldRenderSecond() ? this.renderSecond() : this.renderSomethingElse() }

Три раза скроллить будете? Голова не начнет болеть?
И не надо рассказывать что так на React не пишут. Пишут, да еще и гордятся этим.
0
+1 –1
TheShock ,  
Люди не зря придумали понятие абстракции. Вам достаточно знать имя метода и понимать: «Он отрендерит second». Нету необходимости знать детали реализации всей пирамиды при работе с определенным методом.
–1
TimTowdy ,  
В том-то и дело. Я не хочу знать детали реализации. У меня четкая задача: понять какой будет итоговая разметка. Затратив на это минимум усилий. И чем больше джаваскрипта в разметке, тем больше понадобится усилий для понимания.

Скажете задача надуманная? Вот вам пример из жизни, юзер репортит баг: «не смог купить т.к. кнопка оплаты куда-то уехала». Естествнно предполагаем что в каких-то случаях едет верстка. Ну и что толку с вашей великолепной абстракции? Сильно она кому-то поможет?

Предложите забить т.к. юзер не привел шаги для воспроизведения? Извините, позволить конверсии просесть на неизвестную величину на неизвестный срок для бизнеса это не вариант.

Вы мыслите с позиции программиста: делаю фичу, пишу код, ввожу абстракцию…
А я мыслю с позиции жизненного цикла проекта: ввести в команду нового человека, пофиксить баг, добавить новую фичу не повысив ментальную нагрузку, позволить членам команды с разным уровнем опыта продуктивно работать в команде, продолжить работу если важный разработчик попал под автобус, минимизировать технический долг… И с этой точки зрения я зачастую предпочту именно Vue, а не React.
0
+1 –1
TheShock ,  
Естествнно предполагаем что в каких-то случаях едет верстка. Ну и что толку с вашей великолепной абстракции?

Смотрим итоговую разметку и правим CSS, у нас ведь не 90-ые, когда стилизация делалась кучей вложенных дивов. Верстка — исключительно семантическая. Или у вас не так?
+1
raveclassic ,  
Оппа, вызов метода — сохраняем прочитанную часть шаблона в «мозговой стэк», скроллим до renderSecond() читаем его, вычисляем, прыгаем назад по стэку, читаем дальше…

А вы, встречая в маркапе кастомный компонент, каждый раз переходите в него и смотрите, а что же он там рендерит? Ну чушь же. Компонент определяет свое предназначение своим именем, точно так же и с методами.


А если у вас там такое выражение?

Можно подумать, подшаблоны и зоопарк v-if/ng-if/что-угодно-if-switch-unless выглядят лучше. Голова болит еще хуже, так как приходится переключаться между языками.


//…
// еще 5 экранов кода
//…

Три раза скроллить будете? Голова не начнет болеть?

Бейте на подкомпоненты. Пять экранов html точно так же не вызывают ничего кроме изжоги.


И не надо рассказывать что так на React не пишут. Пишут, да еще и гордятся этим.

Вас просто бесит, что вместо привычного html вы видите какую-то инопланетную js-угрозу. А сказки про неперевариваемость верстальщиками из команды JSX — так совсем полная чушь, убедился на личном опыте. Даже обезьянка поймет, как использовать методы/подкомпоненты для разбиения разметки. Еще и в восторге потом будет.

–1
TimTowdy ,  
А вы, встречая в маркапе кастомный компонент, каждый раз переходите в него и смотрите, а что же он там рендерит? Ну чушь же.

Привел пример выше, совсем не чушь.

Можно подумать, подшаблоны и зоопарк v-if/ng-if/что-угодно-if-switch-unless выглядят лучше.

Да, выглядят лучше т.к. читаем специализированный DSL, а не мегаязык который умеет все.

Голова болит еще хуже, так как приходится переключаться между языками.

Это просто смешно. Придумываем надмножество JS, чтоб не формально не переключаться между языками. Больше не нужно переключаться, ведь наш мегаязык теперь включает в себя абсолютно все!
Напоминает аргументацию креационистов: религия лучше чем наука, потому что религия может объяснить абсолютно все, а наука — нет!

Бейте на подкомпоненты. Пять экранов html точно так же не вызывают ничего кроме изжоги.

Любой условный рендеринг разбивать на подкомпоненты? Нет, спасибо.

Вас просто бесит, что вместо привычного html вы видите какую-то инопланетную js-угрозу.

Да, я использовал JS более 10 лет, и считаю его плохим языком (даже с учетом ES6). Поэтому замену JS+HTML+CSS на JS+JS+JS считаю вредной. Но это тема отдельного разговора.

А сказки про неперевариваемость верстальщиками из команды JSX — так совсем полная чушь, убедился на личном опыте.

В науке личный опыт — самый слабый аргумент.
+1
raveclassic ,  
Привел пример выше, совсем не чушь.

То есть вы серьезно, когда видите что-то вроде <div><avatar/>{user.name}</div> ходите в avatar чтобы посмотреть, из чего он состоит? Мне вас жаль, абстракциями совсем не пользуетесь?


а не мегаязык который умеет все.

Это не мегаязык, который умеет все, а, эм… просто язык, привычный, стандартный. Зачем мне учить что-то новое для решения проблемы, если мой инструмент и так ее решает? Еще и хорошо. Или у вас унаследованная от пхп паранойя по поводу хождения в базу из шаблонов?


Напоминает аргументацию креационистов: религия лучше чем наука, потому что религия может объяснить абсолютно все, а наука — нет!

Мои предположения о вашей паранойе крепнут.


Любой условный рендеринг разбивать на подкомпоненты? Нет, спасибо.

Что-то вы мечетесь. Я говорю вам, что нужно разбивать 5-страничные портянки, а не ветки условий.


Да, я использовал JS более 10 лет, и считаю его плохим языком

Ну вот и сложился пазл.


В науке личный опыт — самый слабый аргумент.

Вы уж простите, но промышленное производство, а именно этим занимаются команды разработки, в случае верстки далеко от науки. И в этом случае выводы диктуются опытом.

+1
TimTowdy ,  
То есть вы серьезно, когда видите что-то вроде <avatar/>{user.name} ходите в avatar чтобы посмотреть, из чего он состоит? Мне вас жаль, абстракциями совсем не пользуетесь?

Вы пример-то прочитали? Есть баг, в каких-то (неизвестных) условиях ломается верстка. Чем тут поможет ваша абстракция avatar?
Представьте себе, возможно придется полезть и в него. Может аватар, загруженный из фейсбука, рендерится с неправильными размерами и смещает форму оплаты? Или у юзеров без аватара placeholder рендерится два раза вместо одного? И, в зависимости от размера экрана (или браузера) на мобильном девайсе, это смещает форму.

Да, придется открывать разные файлы, и скроллить туда-сюда. Но ради абстракции с этим можно смириться. А вот ради условных операторов — вряд ли.

Зачем мне учить что-то новое для решения проблемы, если мой инструмент и так ее решает? Еще и хорошо.

Когда у вас есть только молоток, все вокруг кажется гвоздями.

Вы уж простите, но промышленное производство, а именно этим занимаются команды разработки, в случае верстки далеко от науки.

У вас аргументация демагога, причем тут промышленное производство? «Это полная чушь, потому что я убедился на личном опыте».

В общем, я вижу что вы слишком эмоционально реагируете на критику своего золотого молотка и начинаете переходить на личности. Надеюсь в дальнейшем будете способны на конструктив.
0
raveclassic ,   * (был изменён)
Представьте себе, возможно придется полезть и в него. Может аватар, загруженный из фейсбука, рендерится с неправильными размерами и смещает форму оплаты? Или у юзеров без аватара placeholder рендерится два раза вместо одного?

Так может это проблема аватара, как отдельного элемента интерфейса? Может, он плохо оттестирован, плохо изолирован, раз так сильно влияет на свое окружение? В любом случае, вы первым делом открываете инспектор и ищите причину сдвига формы. Границы компонентов достаточно хорошо прослеживаются. Найдя дефект, вы знаете внутри какого компонента он находится. Разница между vue и react тут нулевая.


Дальше, это все не имеет никакого отношения к условиям. Отдельный метод под ветку ничем не отличается от отдельного компонента под ветку. Если вы не хотите терять контекст при работе с разным блоками (родителем и разметкой ветки), пожалуйста — используйте && или тернарники. Без выкрутасов, без тройного сальта назад, без dsl.


Когда у вас есть только молоток, все вокруг кажется гвоздями.

Как же уже заколебала эта фраза, лезущая из всех щелей. Вы ребятам из команды kotlin тоже самое скажете? "Вы с ума сошли! Зачем вам один язык под все? Есть же такой клевый зоопарк на все случаи жизни"


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

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

+1
TimTowdy ,  
Найдя дефект, вы знаете внутри какого компонента он находится.

Вы все еще не поняли? Баг вам воспроизвести не удалось. Дефект не найден. Но он есть. Толку от вашего инспектора, если не можете его ни воспроизвести, ни даже узнать как конкретно он проявляется? Все что вам сказал юзер: «не видно кнопку оплаты». Потенциальных причин — миллион.

Моя позиция — чем проще вам охватить взглядом разметку и удержать ее в голове, тем легче будет найти чем этот баг вызван.
В случае с React это 100% будет сделать сложнее — просто потому что он позволяет (и разработчики очень этим пользуются) сильнее размазать разметку. Просто потому, что удержать в голове разметку, которая генерируется языком широкого назначения — сложнее.

Но поскольку для вас React — венец творения, золотая пуля, а любая критика — богохульство, ввожу вам объективную метрику: средняя удаленность кусков разметки компонента помноженная на количество этих кусков. Очевидно, что чем ниже этот показатель, тем проще понять разметку компонента. Очевидно, что по этому показателю, React проигрывает Vue. Насколько это критично — каждый решает сам.
Причина нашего несогласия: для меня этот показатель более важен, чем для вас.
–1
TheShock ,  
ввожу вам объективную метрику: средняя удаленность кусков разметки компонента помноженная на количество этих кусков

Ну, очевидно, по такой странной «объективной метрике» Vue вам ровно так же не подходит, а необходимо писать html без всяких компонентов для каждой страницы, где все в одном файле. Ну, то есть, вы, по сути, просите php 3.
0
TimTowdy ,  
Не нужно передергивать. Я нигде не сказал что это единственная метрика которой стоит руководствоваться. Я привел ее для примера человеку, который, похоже, наивно полагает, что React в абсолютно любой ситуации превосходит Vue.
Ну и кстати в php3 тоже запросто можно разбросать разметку по разным частям файла. Так что тут вы ошиблись.

Если уж следовать вашей демагогии, то я прошу чистый HTML без какой-либо логики. Потому что это именно то, что будет отображено на странице. И в какой-то момент вам нужно понимать, как ваш код на языке общего назначения, преобразуется в разметку. Чем дальше вы от этого уходите, тем сложнее будет работать с версткой. В React этим пожертвовали, не дав, на мой взгляд, никаких весомых преимуществ.

Причины, как я уже писал, скорее всего в истории этих библиотек:
Vue — очередная попытка создать удобный JS-фреймворк, с учетом ошибок предшественников.
React — попытка создать быстрый реактивный JS-фреймворк основанный на VirtualDOM.

Оба со своими задачами справились прекрасно. Но Vue около года назад просто взял и добавил себе скорость React как одну из деталей реализации (VirtualDOM). А React не может сделать то же самое со своим дизайном. Именно поэтому вокруг Vue сейчас тот же хайп, который в 2015 был вокруг React.
–1
TheShock ,  
Я привел ее для примера человеку, который, похоже, наивно полагает, что React в абсолютно любой ситуации превосходит Vue.

Вы ошибаетесь. Я никогда не пользовался Vue и не знаю, какой он. Если вы внимательно почитаете мои комментарии, то увидите, что я никогда не сравнивал Реакт с Vue и вообще не давал оценку Vue. Ибо, как я уже сказал, я понятия не имею, что там творится в Vue (хотя лично я тоже крайне не люблю разметку на псевдоязыке а-ля Ангулар)

Я как раз говорю, что вынос кода в метод — это благо, а не наказание, без контекста Vue. То есть именно в Реакте то, что я могу вынести код в метод — это очень круто и помогает разработке, код становится читабельным, метод Рендер меньше и это хорошо.

Чем дальше вы от этого уходите, тем сложнее будет работать с версткой

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

У нас есть готовая верстка в браузере, у нас есть даже для браузера Реакт тулы, которые покажут, какой именно компонент рендерит этот кусок ДОМа.

Но лично я никогда не пользовался этими тулами, ибо… не было необходимости.

У меня Реакт рендерит логичную семантическую верстку и, пожалуй, не бывает момента когда ее нужно править ради баг-фикса. Баг или в JS-логике или в CSS.
+1
TimTowdy ,  
Вы ошибаетесь. Я никогда не пользовался Vue и не знаю, какой он. Если вы внимательно почитаете мои комментарии, то увидите, что я никогда не сравнивал Реакт с Vue и вообще не давал оценку Vue

Я ведь не вам отвечал, когда привел свою метрику, а raveclassic. Пример метрики привел для именно для него.

У нас есть готовая верстка в браузере
Я же специально для этого привел пример с багом: верстка в браузере есть, но абсолютно никак не помогает решить задачу.

Верстка в браузере этого лишь один из возможных вариантов интерпретации шаблона/кода. Добавьте 5 условий — получите +32 варианта верстки.

Браузеры вот уже почти 25 лет интерпретируют HTML. От этого никуда не уйти. Теперь вам нужно придумать некоторую абстракцию, которая описывает как состояние преобразовывается в HTML. Чем ближе ваша абстракция (template/JSX) к конечному результату (HTML), тем проще ею пользоваться.

Вот вам банальная задача: отобразить список имен из массива. Т.е. преобразовать это:

const users = ['Alice', 'Bob', 'Charlie']

в это:
<ul>
    <li>Alice</li>
    <li>Bob</li>
    <li>Charlie</li>
</ul>


Решение на Vue:
<ul>
    <li v-for="name in users">{{ name }}</li>
</ul>


Решение на React (взял из официальной документации):
const names = users.map((name) =>
  <li>{name}</li>
);

return (
  <ul>{names}</ul>
);


Просто помедитируйте на эти три куска кода пару минут. Подумайте, какую ментальную нагрузку на разработчика несет преобразование из кода на React/Vue в конечный результат.

И я даже не упоминаю о том, что даже такую простую задачу как вывод списка, на React можно сделать несколькими разными способами. Еще больше способов найдется для условных операторов.
Не вспоминаю про className, inline-стилях, убогом setState вместо привычного присваивания, boilerplate коде…

У React была отличная концепция: components, unidirectional data-flow, functional UI, VirtualDOM. Прекрасные вещи. И все они есть во Vue. И реализованы на порядок лучше (просто потому, что у Vue была возможность учесть недостатки React).
+1
TimTowdy ,  
Раз уж я упомянул условные операторы, просто оставлю здесь для будущих поколений варианты из этого треда.

Итак, задача в голове программиста звучит так:
«рендерить компонент Second, только если second равно true».

React (ваоиант 1):
return (
  <div>
    <First />
    {second && <Second />}
    <Third />
  </div>
);


React (ваоиант 2):
return (
  <div>
    <First />
    { (()=> { if( second ) return <Second /> })() }
    <Third />
  </div>
);


React (ваоиант 3):
import If from 'composable-js'
return (
  <div>
    <First />
      { If( ()=> second , ()=> <Second /> ) }
      </If>
    <Third />
  </div>
);


React (ваоиант 4):
renderSecond(){
    if (this.second){
        return <Second />
    }
    return null
}
// ...
return (
  <div>
    <First />
    {this.renderSecond()}
    <Third />
  </div>
);


Vue:
<div>
  <First />
  <Second v-if="second" />
  <Third />
</div>


Абстрактный щаблонизатор:
<div>
  <First />
  {% if second %}
    <Second />
  {% endif %}
  <Third />
</div>
0
vintage ,   * (был изменён)

Вы бы хоть поправили в 3 варианте лишний закрывающий тег, который я не успел удалить :-)


Ну и вариант на view.tree тогда:


sub /
    <= Head $my_first
    <= Body $my_second
    <= Foot $my_third

Body() {
    return this.body() ? super.Body() : null
}
0
raveclassic ,  
Я привел ее для примера человеку, который, похоже, наивно полагает, что React в абсолютно любой ситуации превосходит Vue.

Видимо, вы наивно видите то, что хотите видеть.


Я ведь не вам отвечал, когда привел свою метрику, а raveclassic. Пример метрики привел для именно для него.

Какая к черту метрика? Размазанность маркапа по методам? Ну что за ахинея, вы так же размажете маркап по компонентам и будете прыгать из файла в файл. Не хотите — не размазывайте. Не надо только говорить, что возможность декомпозиции это минус и "vue тут явно выигрывает". Повторюсь, вы видите то, что хотите видеть.


Решение на React (взял из официальной документации):

Постеснялись бы хоть.


<ul>
  {names.map(name => <li>{name}</li>)}
</ul>

Подумайте, какую ментальную нагрузку на разработчика несет преобразование из кода на React/Vue в конечный результат.

Вот в том то и дело, что любой порядочный разработчик знает, что преобразование над элементами массива выполняется через map. Везде и всегда. Нужно из массива имен сделать массив элементов списка. Вуаля — map!


И реализованы на порядок лучше (просто потому, что у Vue была возможность учесть недостатки React).

Пока что я не услышал ни одного аргумента в пользу vue кроме лютой субъективщины. Окей, один аргумент — с реактом надо потратить один день (я знаю, что говорю), чтобы научить верстальщика jsx. "Vue тут явно выигрывает"

0
TimTowdy ,  
Постеснялись бы хоть.
Вот в том то и дело, что любой порядочный разработчик знает, что преобразование над элементами массива выполняется через map. Везде и всегда. Нужно из массива имен сделать массив элементов списка. Вуаля — map!
Так я и сделал через map, внимательней посмотрите. Скопировал из документации React один в один. Чего мне стесняться-то?

Окей, один аргумент — с реактом надо потратить один день (я знаю, что говорю), чтобы научить верстальщика jsx.
Вы делите мир на черное и белое: «верстальщик умеет в JSX» и «верстальщик не умеет в JSX». Я же утверждаю, что верстальщик знающий JSX все равно будет менее продуктивен, чем если бы ему пришлось работать с языком, более близким к реальной разметке. Измерить ментальную нагрузку конечно сложно, но по-моему в приведенных мною примерах это довольно очевидно (если смотреть на них без фанбоизма и эмоций).
+1
raveclassic ,  
Чего мне стесняться-то?

Ну вы же давите на "излишнюю разнесенность", специально тогда пишите пример с дополнительной переменной?


Вы делите мир на черное и белое:

Я делю мир на "нужно учить стандартные вещи" и "нужно учить нестандартную отсебятину". Невозможно знать все, мы постоянно учимся. Вопрос стоит в том, что учить — язык или еще один шаблонизатор


что верстальщик знающий JSX все равно будет менее продуктивен, чем если бы ему пришлось работать с языком, более близким к реальной разметке

Я же вам с уверенностью утверждаю, что это не так, так как прямо сейчас целая команда, ранее не знакомая с jsx, работает на таком уровне производительности, который им раньше и не снился. Попутно выучив JS. Одни плюсы.


если смотреть на них без фанбоизма и эмоций

но по-моему в приведенных мною примерах это довольно очевидно

Очевидно, что очевидно это только вам.
Ну и конечно, я все ждал, что меня обзовут фанбоем когда "поток аргументации" иссякнет.

–1
+1 –2
TimTowdy ,  
Ну вы же давите на «излишнюю разнесенность», специально тогда пишите пример с дополнительной переменной?

Еще раз говорю, пример взят из официальной документации React. В программировании бывает вводят дополнительную переменную чтобы код сделать проще для понимания. И посколько к JSX разработчики относятся именно как к коду (ведь он по сути им и является), то и подход используют точно такой же. Они таким упрощают понимание алгоритма генерирующего разметку, но усложняют понимание самой разметки. Это tradeoff, в большинстве случаев не осознанный. И далеко не всегда полезный.

Во Vue же, к разметке относятся именно как к разметке. Несмотря на наличие условных операторов, циклов, и последующего преобразования в VirtualDOM.

В React разметка становится кодом на этапе написания приложения. А во Vue — на этапе компиляции. Вы можете сколько угодно с этим спорить, но разметку всегда читать проще, чем код. И программисту, и верстальщику. А код, в 2017 году, пишется именно для того чтоб его читали.
0
YemSalat ,  
Ну тут опять же сводится к поддержке кода и аргументу автора статьи (столько-то символов против стольки-то).
В данном примере я бы вынес в отдельную переменную или функцию, или на худой конец в «ternary expression»:
return (
    {
      (condition)
        ? <Something />
        : null
     }
);

Тут возврат к моему начальному аргументу: «На вьюхи Реакта надо смотреть как на обычный JS...»
0
serf ,  
Single File Components

Это как раз плохой тон все пихать в одни файл, как по мне. Однако это опциональная возможность тк можно подключать шалон + js/css как внешние файлы.

0
Virviil ,  

Если компонент уровня TableRowCell или TableControllPanelButton — почему бы и нет?

0
serf ,  

Потому что это принципиально неправильно все смешивать в один файл, это можно сделать при сборке если нужно, но не на уровне исходников.

+1
VolCh ,  

По разному бывает. Когда для минорных изменений нужно минимум три файла править — тоже как-то не очень правильно. Как по мне, то система должна быть достаточно гибкой, чтобы легко поддерживать разные варианты (де)композиции в зависимости от проекта/команды. Грубо, если в команде в целом "фуллстэк" разработчики, а изменения в проекте в основном локальные, но затрагивающие все элемента "большой триады фронтенда", то компонент в одном файле имеет слишком много плюсов, чтобы от него отказаться лишь из-за того, что один из кандидатов на роль основного фреймворка этот способ не работает.

0
serf ,  

Я не призываю отказаться, Vue как раз позволяет использовать оба подхода.

0
SPAHI4 ,  
https://github.com/zeit/styled-jsx
0
trueClearThinker ,  

Vuex хорош лишь тем, что он встроен в инфраструктуру (тот же devtools). На самом деле есть вопросы к vuex, которые, похоже, разработчик не собирается решать.

0
kellas ,  
https://github.com/alexstep/create-riot-app-ejected/
+9
+11 –2
Akuma ,  
Уж не знаю какую по счету статью про Vue vs React читаю, но никак не пойму на что напирают сторонники Vue?

1. Хватит гнобить JSX. Это дело вкуса, но мне, как и многим людям, он нравится.

2. Мне, как и многим людям, НЕ нравятся шаблоны в строках. По большому счету из-за отсутствия поддержки в IDE. Поправьте, если ошибаюсь и они уже работают так же «ровно» как JSX.

3. Дайте четкое определение Custom Controlls. То, что в статье — просто отдельный компонент и он на Vue ничем не отличается от остальных.

4. Создание компонентов в React — история? Скорее четверостишье. Просто функция в самом простом варианте. Впрочем, класс с render() не слишком сложнее.

В общем, кроме расширения через прототип (вряд ли когда-нибудь понадобится, ну да ладно) плюсов вы не привели.

Так вот: не надоело еще? Я имею ввиду писать статьи уровня «смотрите, мой ХеллоуВорлд круче, чем на Реакт». Напишите что-нибудь сложнее вывода {{message}}, используя фичи, которые есть только в Vue и тогда это будет сравнение преимуществ. А пока это больше похоже на реферат по информатике.
0
+1 –1
raveclassic ,  
на что напирают сторонники Vue

На то что не react и не angular.


Это дело вкуса, но мне, как и многим людям, он нравится

К сожалению это закоренелое убеждение, что все кончается html'ем


так же «ровно» как JSX.

Или, еще лучше, TSX


кроме расширения через прототип

Я правильно понял, что тут патчинг глобального прототипа приводится за преимущество? Эм...

–1
+1 –2
rboots ,  
Что за деление на сторонников того и другого фреймворка? Посмотрите голосование, среди тех, кто пробовал Vue довольных более чем в 5 раз больше. Есть те, кто ещё не пробовал, и, собственно, «сторонники». Поэтому ждём вас в наших рядах. А шаблоны в строках я тоже не люблю, это для демонстрации, а типичный компонент выглядит как-то так:

Заголовок спойлера
<template>
    <div class="ViewTestBusinessReport animated fadeIn">
        <div class="row">
            <div class="col-12">
                <div class="card" v-if="!loaded">
                    <div class="card-block">
                        Загрузка...
                    </div>
                </div>
                <div class="card" v-if="loaded">
                    <div class="card-block candidate-info">
                        <h3>Кандидат</h3>
                        <div class="row">
                            <label class="form-group col-6">
                                <b>ФИО:</b>
                                <input type="text" v-model="candidateData.fio" 
                                       class="form-control"
                                       placeholder="не заполнено" readonly>
                            </label>
                            <label class="form-group col-6">
                                <b>Позиция:</b>
                                <input type="text" v-model="candidateData.vacancy" 
                                       class="form-control"
                                       placeholder="не заполнено" readonly>
                            </label>
                            <label class="form-group col-6">
                                <b>Телефон:</b>
                                <input type="text" v-model="candidateData.phone"
                                       class="form-control" 
                                       placeholder="не заполнено" readonly>
                            </label>
                            <label class="form-group col-6">
                                <b>E-mail:</b>
                                <input type="text" v-model="candidateData.email"
                                       class="form-control"
                                       placeholder="не заполнено" readonly>
                            </label>
                            <label class="form-group col-12">
                                <b>Примечание:</b>
                                <textarea v-model="candidateData.comment" class="form-control"
                                          placeholder="не заполнено" readonly></textarea>
                            </label>
                        </div>
                    </div>
                </div>
                <div class="card" v-if="loaded">
                    <div class="card-block" v-if="results">
                        <h3>Результаты теста</h3>
                        <div v-for="metricResult in results">
                            <b v-text="metricResult.title + ':'"></b>
                            <span v-text="getMetricRating(metricResult) + ' из 100'"></span>
                        </div>
                        <br />
                        <button type="button" class="btn btn-default"
                                @click="print" v-if="beta">Распечатать</button>
                        <router-link :to="'/test_science_result/' + testId" 
                                     class="nav-link" v-if="beta">Научный отчёт</router-link>
                    </div>
                    <div class="card-block" v-if="!results">
                        Кандидат ещё не прошёл тест. Ссылка на прохождение теста:
                        <CopyInput :text="testLink"></CopyInput>
                    </div>
                </div>
            </div>
        </div>
    </div>
</template>

<script>
    import CopyInput from '../../components/CopyInput.vue'

    export default {
        name: 'test_business_report',
        components: {
            CopyInput
        },
        props: ['testId'],
        data: function () {
            return {
                beta: window.beta,
                loaded: false,
                candidateData: null,
                results: null
            };
        },
        created: function () {
            this.testLink = config.host + 'test.html#/link/' + this.testId;

            axios.post('/api/test_report/business', {
                testId: this.testId
            })
                .then(this.onGetTestResults.bind(this))
                .catch(this.onAjaxError.bind(this));
        },
        methods: {
            onGetTestResults: function (response) {
                this.candidateData = response.data.candidateData;
                this.results = response.data.results;
                this.loaded = true;
            },
            getMetricRating: function (metricResilt) {
                var rate = metricResilt.plus / (metricResilt.plus + metricResilt.minus);
                return Math.round(rate * 100);
            },
            complete: function () {
                document.clearCookie('activeTest');
                location.href = '#/dashboard';
            },
            print: function () {
                console.log('Print');
            },
            onAjaxError: function (error) {
                console.error(error);
            }
        }
    }
</script>

<style lang="less">
    .ViewTestBusinessReport {
        .candidate-info {
            input[type="text"].form-control,
            textarea.form-control {
                background: #fff;
                color: #444;
                border: 0;
                padding: 0.3rem 0;
            }
        }

        #CopyField {
            border: 1px solid rgba(0, 0, 0, 0.15);
            color: #888;
        }
    }
</style>

+3
+5 –2
Akuma ,  
Вы вкурсе, что в этом опросе можно выбрать только один вариант?
Я вот например выбрал «Не планирую использовать». И нравится/ненравится не выбирал.
Причем, я не говорю, что он мне не нравится. Я говорю, что это уже 100500-я статья про «Почему Vue лучше» и в 100500-й раз в ней НЕ написано о том почему Vue лучше.

Давайте проще. Основная фича React — это отсутствие собственных обязательных выдумок. Все делается на чистом JS. Абсолютно все.

У Vue же болячки первого Angular: выражения в шаблонах ограничены, присутствуют собственные атрибуты, собственные изобретения. Первый Ангуляр явно показал чем это плохо. Он показал, что все эти ng-if заставляют разработчика бороться с фрейморком. То же будет и с Vue, я вас уверяю.

Простой пример. У меня есть обычный JS Array:
let list = [{type:'one'}, {type:'two'}, {type:'three'}]

Мне нужно вывести список, который будет в зависимости от type рендерить разные компоненты.

React:
{list.map(item => {
    switch(item.type){
        case 'one':
        return <ComponentOne />;
        ....
    }
})}


Vue:
<component-one v-if="item.type == 'one'" />
...


Видите разницу? В первом случае это просто JS, который вернет список. Во втором это HTML с кастомными атрибутами.

Скажете, что не слишком явное преимущество? А если нужно в каждый компонент передать разные props и еще и вычислять их по разному для каждого компонента?

React удобен тем, что он простой как помидор. Vue напоминает первый Ангуляр без DI и с некоторыми упрощениями, но не более того. Сначала все радуются, потом начнут с ним бороться.
–1
taujavarob ,   * (был изменён)
Akuma
React удобен тем, что он простой как помидор. Vue напоминает первый Ангуляр без DI и с некоторыми упрощениями, но не более того. Сначала все радуются, потом начнут с ним бороться.
Читаю в коментах через строку и так понимаю сам себе:
  • React простой как помидор, Vue простой но эта та простота что хуже ...
  • React сложен, — вот Vue простой.
  • React простой как помидор, Vue простой но эта та простота что хуже ...
  • React сложен, — вот Vue простой.
  • ...


Простота хуже воровства — это мнение стороны, пострадавшей от этой простоты, и некого обвинить, и некому предъявить. То есть, если тебя ограбили, ты можешь обратиться в суд, и, возможно, вернешь украденное, а если сам сдуру отдал? А если кто-то тебя подставил по простоте своей? ( взято на просторах инета)
0
+2 –2
TimTowdy ,   * (был изменён)
Рендеринг списка динамических компонентов это стандартная задача, и во Vue уже есть готовое решение. Вам не нужно решать каждую проблему написанием JS — подавляющая часть проблем уже решены.

Вот как на самом деле будет выглядеть рендеринг списка динамических компонентов (пишу по памяти т.к. я не фронтэндщик):
<component v-for="item in list" :is="item.type">


Видите разницу? В вашем случае, чтоб понять что рендерится динамический компонент нужно прочитать несколько строк JS перемешанного с html.
В случае DSL от Vue сразу видно что происходит. Никаких swtich/case/return <JSX>. Одна строка.Этим он и подкупает — ментальная нагрузка на разработчика гораздо ниже.
+5
+7 –2
Akuma ,  
Эм. Вот я далеко не первый год в веб-разработке и с ходу я не скажу, что делает ваш код.
Даже при том, что я очень активно использовал Angular 1 когда тот появился.

Он возьмет имя компонента из item.type? Т.е. оно должно 100% совпадать.
Что будет, если не совпадет?
Как мне передать props в эти компоненты?
«Какие» компоненты он будет использовать?
IDE покажет использование этих компонентов этим кодом?
Как мне скрыть некоторые компоненты в зависимости от props?

И я не прикалываюсь. Реально при многолетнем опыте я не знаю как это сделать на Vue без чтения документации. А вот как это сделать на JS — поймет даже школьник.
Это все болячки первого Ангуляра, я еще раз повторюсь.

Vue этим подкупает, согласен. Если выучить синтаксис конечно. Но потом вы начнете бороться с фреймворком, т.к. Vue не позволяет «ходить на лево».

У React безусловно тоже есть свои болячки, но они обычно связаны со сторонними библиотеками. А «чистый» React полностью выполняет свои задачи.
+2
+3 –1
TimTowdy ,  
Эм. Вот я далеко не первый год в веб-разработке и с ходу я не скажу, что делает ваш код.
Все правильно. Вы не скажете, потому что вы не разработчик на Vue… Точно также не-React разработчик вообще ничего не поймет в вашем React коде. Это нормально, суть не в этом.
Суть в том, какую ментальную нагрузку несет фреймворк уже после того, как вы его изучили.

Ваш пример как раз очень наглядный: Vue-разработчику, для того чтоб понять что рендерится динамический компонент достаточно увидеть :is. Потому что для типовой задачи сделали типовое решение. А вот в случае React придется прочитать кучу (по сравнению с 3 символами) кода: вызов map(), стрелочная функция, switch/return… Более того, дайте эту задачу трем реакт-разработчикам, и они выдадут три РАЗНЫХ решения (вы сделали map, кто-то сделает функцию с for, кто-то заведет отдельный object с маппингом имени в компонент...). В случае с React у вас всегда будет JS, который разные разработчики напишут по-разному. А иногда даже один и тот же разработчик напишет это по-разному в зависимости от настроения или понимания (например для трех компонентов сделает switch, а для 20 — отдельный объект).

В этом большая проблема современного фронтэнда — любую задачу вы привыкли решать написанием нового JS-кода. Когда у вас есть только молоток, вам везде мерещатся гвозди.

Он возьмет имя компонента из item.type? Т.е. оно должно 100% совпадать.

Да. Точно также как оно должно на 100% совпадать в вашем <ComponentOne />. Только у вас теперь еще неявное отображение "one" -> ComponentOne, которое тоже нужно держать в голове, увеличивая ментальную нагрузку.

Как мне передать props в эти компоненты?

Динамические props? Элементарно:
<component v-bind="item.props">

А что в React? Опять куча JS?

«Какие» компоненты он будет использовать?
Насколько я понимаю (пусть знатоки поправят, если ошибаюсь), либо глобальные, либо заданные в родительском компоненте, если вы хотите ограничить их набор. Опять-таки Vue выигрывает: типовая задача «ограничить доступные родительскому компоненты» во Vue уже решена: компонент может принимать набор доступных ему дочерних компонентов. А что в React? Опять кастомный JS, который разные разработчики напишут по-разному?

IDE покажет использование этих компонентов этим кодом?
Не понял вопрос. Но если честно, аргумент насчет IDE всегда слаб. Когда-то IDE и JSX не отображали. Кому нужно — тот настроит. В случае с Vue, насколько я знаю, настраивать обычно приходится меньше.

Как мне скрыть некоторые компоненты в зависимости от props?
Если «скрыть» — это поведение компонента, то возможно его стоит вынести в сам компонент.
Ну, а для простых случаев есть директива v-show (либо v-if, если компонент нужно не скрыть, а вообще не создавать):
<component v-show="item.isVisible">


Видите в чем прелесть? Вы сейчас спрашиваете как решить какие-то стандартные задачи, и во Vue они уже решены. Ответы в документации, а не на stackoverflow. И решение одно, и с ним уже знакомы все разработчики. Вам не нужно выбирать из десятка модулей, а потом объяснять каждому новому члену команды как на вашем проекте задаются стили компонентов, и почему это отличается от того, что он делал в другой компании.
0
+1 –1
indestructable ,  

Что может быть стандартнее Javascript на фронте? Уж точно не DSL Vue.

+1
raveclassic ,  

Я уже молчу про годами складывающиеся функциональные паттерны (а мы понимаем, что реакт со всей своей декларативностью это про фп). Компоновка интерфейса следует знакомым и понятным законам. Компоненты высшего порядка, букет всевозможных Maybe/Either, совершенно другой уровень абстракции, совершенно другой уровень переиспользуемости.

0
+1 –1
TimTowdy ,  
Вы немного путаете контекст. «Стандартность» JS на фронте нужна браузерам, т.е. среде исполнения. Но никак не программистам. Им этот «стандарт» нужно читать, а не исполнять. И читать всегда проще именно DSL. В конце концов, именно для этого DSL и создаются.

Стандарт — это не просто «один язык, один фреймворк, один фюрер». Стандарт — это в первую очередь ограничения. И строгий DSL как раз эти ограничения задает. В отличие от динамического JS, который наоборот, дает слишком большую свободу.

К сожалению Javascript/React никак не способствуют написанию кода в стиле «There should be one-- and preferably only one --obvious way to do it». Поэтому ваша абстрактная «стандартность» разбивается о реальность разработки.

Пример: во Vue один способ вывести список компонентов: директива v-for. А знаете сколько различных способов вывода списка компонентов я видел в React? Пальцев рук не хватит, чтоб посчитать.
0
Akuma ,  
А знаете сколько различных способов вывода списка компонентов я видел в React?

Ммм… один? Отдать массив компонентов. Это такой стандартный элемент JS со времен динозавров. Его все знают и не нужно читать документацию :)
+2
TimTowdy ,  
Возьмите 10 разработчиков, попросите каждого написать код, который выведет список компонентов, и сравните результаты. Везде «отдать массив компонентов» будет сделано по-разному. for, for of, map, _.each, стрелочные функции vs обычные, итерация внутри JSX либо снаружи… Нет, вы конечно во всем этом разберетесь довольно быстро, в конце концов это просто генерация массива. Но ментальная нагрузка будет выше.

Честно, я не понимаю зачем вы спорите. Хороший DSL всегда проще читать чем GPL. React-сообщество почему-то категорически отрицает разметку как отдельную область, аргументируя это тем, что в 201х году нельзя не знать JS, поэтому разметка через JS это ок. Не ок. Подход «все — джаваскрипт» конечно можно проглотить. Но подход «мухи отдельно, котлеты отдельно» работает лучше.

Реакт, продавая реактивность, VirtualDOM и UI as a function of state незаметно подсунул всем JSX. Многие проглотили, и даже сказали что им нравится. В общем-то тут не было злого умысла: фокусируясь на VirtualDOM в 2013 году, придумать JSX было хорошим решением. JSX действительно улучшал читаемость. Vue (в текущем его виде), тогда был просто невозможен.

Но сейчас не 2013 год. И Vue, и React реализуют идею "UI is a function of state". Вот только и UI, и state во Vue сделаны лучше. Это очевидно каждому, кто сравнивает эти две библиотеки.

Попробуйте задуматься, кто быстрее разберется: Vue-разработчик в чужом Vue коде, или React-разработчик в чужом React коде? На мой взгляд, это должно быть основным критерием выбора библиотеки в 2017 году. И Vue здесь однозначно побеждает.
0
VolCh ,  
Как по мне, то именно сейчас во фронтенде основным критерием должна быть скорость, с которой незнакомый с фреймворком разработчик сможет выполнять реальные задачи в проекте, где он уже есть.
0
TimTowdy ,  
Не согласен.
Проекты ведь не две недели длятся. Время знакомства с фреймворком обычно на порядки меньше, чем длительность участия разработчика в проекте. Грубо говоря, 1% времени разработчик не знаком с фреймворком, 99% времени — знаком. Мне важно насколько эффективен разработчик (и команда в целом) будет в течение этих 99%.
Ваш критерий, мне кажется, применим только если у вас жуткая текучка кадров.
0
VolCh ,  

По разному длятся. И не текучка может быть в привычном смысле, а ротация по проектам (вариант — эпикам) на разных стэках внутри одной компании. И я даже не про аутсорс.

0
TimTowdy ,  
Если уж и брать ваш критерий, то сравнение Vue vs React явно будет не в пользу последнего.
Не зная фреймворк, и Vue и React код разработчику будет казаться сплошной магией.
Но Vue можно освоить за пару часов, в отличие от React. Это на самом деле очень показательно, учитывая что большая часть концепций у Vue и React одинаковые.
0
Akuma ,  
Я вроде и не спорю :) Давайте тогда на этом остановимся. Выбор фрейморка в какой-то степени дело вкуса. Vue — на мой вкус не очень, т.к. я сбежал от первого Angular. Возможно именно это дает свой отголосок.
+2
indestructable ,  

Это все проходили во времена первого Ангуляра. На нем легко писать простые приложения, но очень сложно писать сложные вещи и библиотеки.


Попробуйте написать хороший drag and drop, хороший грид (с настраиваемыми ячейками, редактированием, заголовками и т.д.).На реакте это написать довольно легко (с учетом, конечно сложности самого решения) — Реакт не будет мешать, а будет только помогать — всей мощью Джаваскрипта.


На Vue вы будете бороться с шаблонизатором — я это понял, как только прочитал про "слоты", которые, как я понимаю, являются аналогом трансклюдов Ангуляра.


В реакте у вас нет слотов, а есть функции и объекты, из которых вы можете создавать другие функции и другие объекты. Поэтому в Ангуляре (да и скорее всего в Вью) никогда не будет, например, декораторов для компонентов, при помощи которых можно сделать, например, редактирование по маске для любого input, даже из third-party component set.


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

0
indestructable ,  

Посмотрите, как сделаны гриды для первого Ангуляра, тот же Кендо. Там компонентностью и не пахнет даже. Огромный объект конфигурации, строковые шаблоны на DSL шаблонов от Кендо, это просто страх и ненависть. И по-другому не сделаешь.


Есть ли во Вью какой-нибудь прогресс с этим?

+1
DarthVictor ,  
Справедливости ради гриды от кендо написаны на чистом jQuery, для AngularJS там только обертка. Что не мешает им быть функциональнее абсолютно всех гридов для ангуляра / реакта, а также рискну предположить, что и для Vue.js/Elm/любой фреймворкнейм
+2
rboots ,   * (был изменён)
Заказывали? Получайте . Первое что нашлось в google. Десяток готовых гридов, инпуты и прочее. А на Ангуляре 1 со сторонними компонентами плохо было потому, что он плохо приспособлен под это был.
0
+1 –1
TheShock ,  
На реакте это написать довольно легко (с учетом, конечно сложности самого решения) — Реакт не будет мешать, а будет только помогать — всей мощью Джаваскрипта.

Иронично, но я не видел на современных фреймворках (ни в одном) такие же клевые штуки, которые столь же легко подключались бы, как возможности, например JQuery UI. Тот же select в Реакте значительно хуже, чем в JQuery UI.
+1
vintage ,  
Тот же select в Реакте значительно хуже, чем в JQuery UI.

Чем именно хуже?

–1
TheShock ,  
Признаюсь честно — не помню. Вы пользовались и тем и другим?
0
vintage ,  

Нет, мы пилим своё решение. Вот и интересуюсь, что именно вам не хватает в существующих.

+1
s256 ,  
Я сейчас скажу страшное — в Vue тоже есть render-функции и тоже можно использовать vanilla.js для написания чистых компонентов. То есть вы в праве не использовать шаблонизатор и если возникает потребность в действительно сложной логике — на Vue это можно сделать в React-like стиле.
–1
raveclassic ,  

Ну и зачем тогда vue?

0
Fragster ,  
потому что в 99.753% случаев эти рендер функции не нужны?
0
denismaster ,   * (был изменён)
https://github.com/eastbanctechru/right-angled
Очень удобный грид(список) для ангуляра(4) Работает на директивах и нескольких компонентах(по сути управляют отображением). Разметка любая может быть.

Что касается кастомных атрибутов, то они очень даже пригождаются. Например, когда вижу в коде подобное:
<input type="text" xrm-datepicker />

То сразу становится понятно, что передо мной компонент для выбора даты.
А вот другой пример кода, который управляет отображением:
<div class="panel panel-default" *xrm-role-admin>...</div>

И сразу видно, что здесь добавляем дополнительный атрибут — и блок отображается только, если роль пользователя «администратор».

Редактирование по маске?) Можете рассказать подробно, зачем вообще такая задача?)
Но, в любом случае, можно написать директиву, которая берет first или third-party input-ы, которые являются детьми блока, к которой директива применяется, после чего их функция writeValue(интерфес ControlValueAccessor, реализуется чем угодно и всеми стандартными инпутами) декорируется с учетом маски и логики редактирования. А разметка остается та же.
0
alek0585 ,  
Покажите, пожалуйста, хорошую библиотеку drag-n-drop на vue. Которая была бы не оберткой над другой библиотекой.
+1
zenkz ,  
Спасибо. Своим комментарием вы только что меня убедили, что Vue.js удобнее реакта.

То, что на реакте занимает 7 строчек js-кода, в которые нужно вчитаться и понять что там происходит, на Vue решается простейшим и понятным аттрибутом.

По поводу ограниченности выражений в шаблонах. Не могу сказать как это работало в ангуляре, но в knockout.js достаточно было сделать computed переменную и поместить логику в неё. А внутри переменной уже чистый js.
–3
+1 –4
rboots ,  
С React без JSX, если честно, возникала мысль: «А какую ценность он вообще добавляет?», так как эти React.createElement очень напоминают просто обёртку над document.createElement с небольшим API для установки атрибутов и вложенности, которая пишется за 50 строчек. Ценность как раз и состоит в DSL, но JSX во-первых очень самобытный и не совместимый ни с какими другими DSL, а во-вторых очень сложно извлекается из React. А главная проблема всей этой конструкции, вместе или по отдельности — сильная связанность всего со всем. Ощущение будто его просто выдрали из реального проекта с многолетней историей и даже не стали особо рефакторить. Писать на JavaScript я и на VanillaJS могу, и это не такой уж плохой путь, кстати. Он ещё проще. А React слишком много всего просит за ту простоту функционала, или скажете у него низкий порог входа?
Vue добавляет сложности, но самую малость, не больше чем обычная библиотека. Шаблоны там стандартные, знакомые ещё с Angular, Knockout и похожие на многие серверные. А самое главное он эффективно отделяет логику от представления, шаблон можно целиком переверстать не затрагивая основную логику, можно начать разработку до этапа дизайна, просто по ТЗ, и заранее иметь готовую логику, можно органично проводить А/В тесты, опять же не трогая основной код. Много чего можно, что с концепцией «всё в js» становится сложнее. HTML это отличный инструмент для создания View и не нужно от него отказываться.
+6
+7 –1
Akuma ,   * (был изменён)
React предоставляет быстрый рендеринг за счет сравнения DOM в памяти + shouldComponentUpdate. Это шаблонизатор и ничего более.

JSX и не должен быть совместим с чем-то другим. Он создавался для React и нечего его использовать отдельно. Впрочем, там «нового» ничего и нет, лишь пара фигурных скобок. Остальное HTML и JS.

Где вы видели шаблонизатор из которого потом нужно что-то извлекать? Это маразм. Хватит. Вы пишите шаблон под конкретный шаблонизатор. Всегда, везде и в любом языке.

Да, его выдрали из ядра Facebook, по сути. И у них это неплохо получилось.

Да, у него низкий порог входа. Куда ниже чем у Vue. Потому что react — шаблонизатор, а не фреймворк.
Кстати Babel вы все равно будете использовать ради ES6, а если нет, то продолжайте мучить себя.

Зачем отделять логику шаблона от самого шаблона? Где вы нахватались этих «умных» выражений про отделение логики? Логика шаблона — это не логика приложения. А если вы всю логику приложения пихаете в React компонент, то либо делайте это осознано, либо не делайте вообще, либо не жалуйстесь. v-if это тоже логика, давайте ее выделим в отдельную библиотеку?

И все же, давайте вернемся у статье: в чем преимущества и уникальность Vue? В статье лишь избитый Todo-list, который скоро встроят в Хром и он будет запускаться просто тегом <todo-list />, т.к. уже всех достал.

Некоторые пишут про некие «слоты». Я уверен, у Vue есть и другие уникальные фичи, которые будут интересны. Я не пытаюсь холиварить о том, что лучше, я пытаюсь выяснить что умеет Vue. В документации я не нашел дял себя ничего интересного, а лишь переделанный Angular 1 от которого убежал давным-давно.
+2
rboots ,  
Я «нахватался» этого из 15-тилетней практики, это сильно облегчает работу и если вы этого не используете — вы себя обкрадываете. Да, он очень похож на Angular 1, с той разницей, что сделан по человечески, скоупы изолированны, отладка стала информативной, производительность выше. Из нового появились custom controls, которые для реакта не новость и вообще тренд последние 7 лет, но наконец их сделали удобными, совместив синтаксис а-ля polymer, который а-ля нативный, с шаблонизацией через свойства html. Это значит, что когда поддержка нативных custom controls станет мейнстриомо в браузерах — от половины Vue можно будет избавиться, либо она будет работать с бешеной производительностью на нативном рендеринге, да и все другие фреймворки будут двигаться в этом направлении. Решение от Facebook неплохое, но не живучее, о нём забудут так же, как забыли про ExtJS, который предлагал много всего хорошего, но не стал доминирующим, так как сильно отличался от стандартов. Я привожу эти аргументы, так как бесполезно спорить что лучше, шаблоны в js или html, у каждого свои вкусы. Но W3 решили, что нативные custom controls будут на шаблонах в html, а поддержки jsx в браузерах нет даже в проекте. Vue по сути придумали очень мало нового, они как и jQuery, как и babel, как и polymer, просто ускорили будущее.
Про низкий порог входа React, это иллюзия вследствие большого опыта, видимо. Для меня, например, чистый JavaScript проще любых фреймворков, но 90% программистов так не считают, видимо они правы и это просто деформация от долгого использования. Общепринято, что React осваивается тяжелее, я например первые 2 недели только и и делал, что гуглил проблемы. А Vue до практического уровня освоился за 2 часа, правда после polymer и angular, у которых он многое взял.
Про уникальные фичи, всё придумано до нас, и вряд ли найдётся что-то совсем революционное. Мой тезис про другое, они просто сделали работу с UI простой и удобной, ориентируясь не на субъективное мнение, а на стандарты отрасли и сильные стороны JavaScript. React, на мой взгляд, создавали люди, у которых первый язык был всё таки не JavaScript, отсюда эта любовь к классам где надо и не надо и прочему, без чего серверники жить не могут. Только JavaScript гораздо глубже и богаче, почему классы, а, например, не монады? Концепция ничем не хуже, весь jQuery на них построен, express активно применяет, а React — нет, потому что его создатели, хоть и талантливые, но JavaScript знают поверхностно.
А babel я применять не буду, синтаксического сахара не так много даёт. Единственное что хочется использовать это async await, но под Node он уже и так доступен, а в браузере вот-вот начнёт быть мейнстримом, пока промисов хватает.
0
raveclassic ,  
любовь к классам где надо и не надо и прочему,

SFC?


почему классы, а, например, не монады?

Теплое и мягкое? При чем тут монады?


потому что его создатели, хоть и талантливые, но JavaScript знают поверхностно.

Потрясающее заявление!


А babel я применять не буду, синтаксического сахара не так много даёт.

Вы ишака поддерживаете?

0
staticlab ,  
React.createElement очень напоминают просто обёртку над document.createElement с небольшим API для установки атрибутов и вложенности, которая пишется за 50 строчек.

Да, на первый взгляд так и кажется. А затем попробуйте вывести массив элементов как в v-for, поменяйте местами любые два элемента массива и добейтесь минимального обновления DOM в 50 строчек.

–4
rboots ,  
Если такая логика есть, её лучше кастомно делать, обёртка здесь не при чём.
parentNode.insertBefore(movingNode, prevNode)

Вот, аж одна строчка, и с минимальными обновлениями DOM.
0
staticlab ,  

Только вы забыли найти movingNode и prevNode

0
raveclassic ,  

Еще и с RAF синхронизироваться

0
Virviil ,  

Во Vue можно писать на JSX. А можно писать на html с атрибутами. Чтобы "побороть" Vue надо написать компонент на JSX. Зато если не надо бороть — можно не писать на JSX.
Поэтому компонент Table пишем на JSX, а компонент SignInUp пишем на атрибутах.
В результате лэйаут может сделать верстальщик (то самое рекламируемое преимущество ангуляра), а компоненты вроде d3 графиков или всплывающих от вебсокета нотификаций — программист.


И в отличие от Ангуляра, у Vue под капотом тот самый "простой как помидор" реактивный рендер цикл. Просто его присыпали "ангулярным" сахарком, и ещё сделали быстроразвёртываемое дев-окружение.
И пользуясь полученным опытом расширили redux наработанными essentials вроде thunk — получили vuex.


Так что vue — это причёсанный react. В котором с помошью сахара можно "писать в стиле ангуляр".

0
JSmitty ,  
Ой, классный пример, спасибо. Прелесть современного Vue.js в том, что он умеет и JSX тоже (и той же ценой). И именно ваш пример (рендер компонента в зависимости от типа в массиве объектов) в одном из проектов именно через JSX на Vue.js реализовывали. Да, это проще, чем городить огород из условного рендеринга в шаблоне или использовать ":is". Логика более очевидная.

Vue.js 2+ позволяет писать компоненты с рендер-функцией, ровно как в React, и поддерживает как JSX, так и нативный интерфейс для создания объектов vnode для Virtual DOM.
–1
raveclassic ,  

Но если вы на vue пишете как на реакте, то зачем тогда vue?

0
JSmitty ,  
Понимаете, он позволяет писать низкоуровнево, но не принуждает к этому. Есть выбор — привычно/удобно так — пиши как нравится, никто не принуждает.

Это существенный плюс, когда в команде есть люди, знакомые с HTML и слабо знающие JS — то синтаксис темплейтов им ближе, чем типовые конструкции React() для достижения того же.
Наши пара проектов (большие и долгосрочные) на Vue.js используют в основном темплейты, но в паре критичных мест используются напрямую рендер-функции.

И потом, стоит понимать, что внутри себя Vue.js 2 компилирует темплейты в рендер-функции. Этот механизм также доступен через API. Т.е. для Vue.js 2 темплейты — это сахар поверх рендер функций, и кмк не особо проблематично сделать аналог для реакта (а, может быть, он уже и существует).

Опять же, с точки зрения использования — магия отслеживания изменений во Vue.js проще в использовании, чем работа с состоянием в React — никаких this.setState() или dispatch(). По мере роста приложения это достоинство нивелируется, но на старте оно сильно облегчает вход (буду откровенен, местами эта магия встает-таки поперек горла).
–2
+1 –3
vintage ,   * (был изменён)

Вот за что я не люблю html шаблоны — в них зачастую очень сложно проследить намерения. Семантики не хватает и разработчики фигачат кто во что горазд. Я попробовал переписать ваш код на $mol, надеюсь правильно угадал всю скрытую семантику.


report.view.tree
$my_test_business_report $mol_list
    test_id \
    test_link_pattern \http://example.org/test.html#/link/{id}
    sub /
        <= Candidate $my_card
            title <= candidate_title @ \Candidate
            content /
                <= Candidate $mol_row
                    sub /
                        <= Name $my_report_param
                            title <= name_label @ \Full name
                            value <= name \
                        <= Vacancy $my_report_param
                            title <= vacancy_label @ \Vacancy
                            value <= vacancy \
                        <= Phone $my_report_param
                            title <= phone_label @ \Phone
                            value <= phone \
                        <= Mail $my_report_param
                            title <= mail_label @ \E-mail
                            value <= mail \
                        <= Comment $my_report_param
                            title <= comment_label @ \Comment
                            value <= comment \
        <= Results $my_card
            title <= results_title @ \Test Results
            content /
                <= metrics /
                <= Beta $mol_row
                    sub / 
                        <= Print $mol_button_minor
                            event_click?val <=> event_print?val null
                        <= Science $mol_link
                            title @ <= science_title \Science report
                            arg *
                                test_science_result <= test_id -
        <= Results_empty $my_card
            title <= results_empty_title \
            content <= Test_link $my_copycode
                title <= test_link_title @ \Link to test
                value <= test_link \
    -
    Metric!id $mol_labeler
        title <= metric_title!id \
        content /
            <= $mol_portion
                portion <= metric_portion 0

report.view.ts
namespace {
    export class $my_test_business_report extends $.my_test_business_report {

        Beta() {
            return this.beta() ? super.Beta() : null
        }

        beta() {
            return this.$.$mol_state_local.value( 'beta' )
        }

        test_link() {
            return this.test_link_pattern.replace( '{id}' , this.test_id() )
        }

        data() {
            return this.$.$mol_http.resource( `/api/test_report/business?testId=${ this.test_id() }` ).json()
        }

        name() {
            return this.data().candidateData.fio
        }

        vacancy() {
            return this.data().candidateData.vacancy
        }

        phone() {
            return this.data().candidateData.phone
        }

        email() {
            return this.data().candidateData.email
        }

        comment() {
            return this.data().candidateData.comment
        }

        metrics() {
            return Object.keys( this.data().results ).map( id => this.Metric( id ) )
        }

        metric_title( id : string ) {
            return this.data().results[ id ].title
        }

        metric_portion( id : string ) {
            const metric = this.data().results[ id ]
            return metric.plus / ( metric.plus + metric.minus )
        }

    }
}

report.view.css
$my_test_business_report_test_link {
    border: var(--mol_skin_light_outline);
    color: var(--mol_skin_passive);
}

report.locale=ru.json
{
    "$my_test_business_report_candidate_title" : "Кандидат",
    "$my_test_business_report_name_label" : "ФИО",
    "$my_test_business_report_vacancy_label" : "Позиция",
    "$my_test_business_report_phone_label" : "Телефон",
    "$my_test_business_report_mail_label" : "E-mail",
    "$my_test_business_report_comment_label" : "Примечание",
    "$my_test_business_report_results_title" : "Результаты",
    "$my_test_business_report_science_title" : "Научный отчёт",
    "$my_test_business_report_results_empty_title" : "Кандидат ещё не прошёл тест",
    "$my_test_business_report_test_link_title" : "Ссылка на прохождение теста",
}

Столько же строчек кода, но меньшее число токенов. Благодаря тому, что каждый блок имеет уникальное имя — сразу понятно что это и зачем. Кроме того, есть возможность переопределить любой элемент "шаблона" извне, без превращения компонента в швейцарский нож с развесистым конфигом. Стили имеют одинаковую специфичность, что опять же упрощает кастомизацию визуализации извне. Плюс практически бесплатная поддержка мультиязычности.

+1
+2 –1
bano-notit ,  

Ну здрасте) Опять вы со своим $mol мелькаете в глазах...

0
+1 –1
vintage ,  

А когда люди со своим Реактом мелькают в глазах — вас не смущает?

0
Odrin ,  
От чтения React кода хотя бы не вытекают глаза.
0
vintage ,   * (был изменён)

Почитайте комментарии в этой теме — у многих вытекают.

+1
bano-notit ,  

Честно? Смущает. Но у них хотя бы ники разные, а Вы один такой неповторимый)

0
raveclassic ,   * (был изменён)

del

+1
xlenz ,  

Лично мне vue.js понравился тем, что проще реакта и ангулара на средних приложений.


Во времена ангулара 1, мне он нравился, потом перешёл на реакт, понравилось больше. Не так давно попробовал ангулар 2 и вернулся на реакт. А потом, без энтузиазма, попробовал vue.js и мне очень понравилось.
За счёт каких-то определённых вещей не скажу, понравилось всё в целом, отсутствие боли, как с другими фреймворками.
Фреймворк не идеален, просто хотел поделиться впечатлением. Пока остаюсь с vue.js.

0
raveclassic ,   * (был изменён)

del

–11
+3 –14
ju5tify ,  
Vue.js > Angular > Говно > Моча > React
0
Sirion ,  
Вы чудовищно неправы, моча лучше говна.
+2
raveclassic ,  

может просто поменять > на <?

+1
Metus ,  

Скажите пожалуйста, а ember мёртв?

0
grimalschi ,  
Жив, но фокус сместился сначала на Angular, потом на React. Сейчас вот Vue мелькает все чаще.

В «тренде» виртуальный DOM, его использует и React и Vue, и многие новые библиотеки (Preact, Inferno, Snabbdom, Mithril...).
+1
s-kozlov ,  
фокус сместился


Как странно вы пишете слово «хайп».
+1
prostofilya ,  
Да нет, помаленьку развивается, вроде как собираются переходить на модульную основу, хотите роуты — качайте эмбер-роут, хотите модели — качайте эмбер дату. Помаленьку развивается движок glimmer, он вроде не такой шустрый как fiber, но на месте не стоит. Оптимизируют, худеет помаленьку. У авторов есть roadmap на офсайте, бросать не собираются.
+9
alist ,  

Отпишусь.


Используем Vue в продакшене, начали с 1.0.x, планировали перейти на 2.0, но сразу же переход сделать времени не было — и хорошо: вышел 2.2, который по честному нужно было бы назвать 3.0, отличий много. Недавно таки перевели приложение на 2.4.


В целом фреймворк действительно очень хороший, приятный в использовании. Недостаток — сторонние библиотеки и плагины. Те, что пишутся командой самого Vue — vue-router, vuex, и тд — отличные, все там хорошо. А вот шаг вправо — шаг влево, и все становится грустно.


Мы взяли одну библиотеку компонентов — Keen UI, которая прошлым летом была супер-популярной и по фичам обгоняла все остальные так, что народ сворачивал свои проекты и шел контрибьютить туда. И буквально на первых же контролах оказалось, что Keen то не умеет, этого не умеет, мы стали компоненты расширять, баги исправлять, засылали пул-реквесты и тд. Какие-то принимали быстро, какие-то медленно. В общем, как обычно. Но проблема и Keen, и других UI-библиотек под Vue, что пишут их реально криво. В самом Vue есть слоты из Web Components, про которые уже выше упоминали, но по факту ребята-авторы видимо пришли с Реакта или других фреймворков, где такого API нет, и им почти не пользуются. И на каждый чих вместо того чтобы просто расширить компонент слотами, приходиться форкать, допиливать и засылать пулреквесты, которые тоже народ не торопится принимать, тк часто доработки довольно специфичные, и никому почем зря раздувать API компонента не хочется.


Ну а сейчас Keen UI заглох — последний коммит в январе, а все остальные библиотеки компонентов либо только-только начинают, либо пишутся китайцами для сингапурцев, и чуть что доки и коммиты на мандарине, и когда вопрос задаешь, тебе никто толком ответить не может.


В результате у нас как почти у всех — свои кастомные UI-элементы. И Вот кажется, что вот он прогресс — Angular, React, Vue, так сильно фронтенд скакнул со времен IE6 и jQuery, — а на деле сидим мы в 2017 году и как лохи делаем свои списки, аккордеоны и модалки.

0
serf ,  

Vuestrap ?

0
negasus ,  
http://element.eleme.io/ не пробовали? Интересно мнение
0
xlenz ,  

Пробовал vue-bulma, тоже что и с keen. Сейчас вот начал работать с элемент, пока не могу ответить однозначно.

+2
s256 ,  
Использовал для написания навороченной админки — в целом впечатления очень положительные. Да над некоторыми компонентами приходится посидеть с напильником, но в целом очень и очень не плохо
0
Fragster ,  
http://bootstrap-vue.js.org/ пилится активно, к выходу 4 бутстрапа. не всё мне нравится, например то, что они сделали с table. Но в остальном — терпимо.
+5
teux ,  

Год назад узнал про Vue, почитал и понял, что он должен быть.
Хотя посыл статьи не разделяю (личные симпатии выдаются за реальное состояние) и сам надеюсь никогда на vue не писать, но…


Технологии фронта очень резко развернулись. Не буду детализировать в какую сторону, суть не в этом. Главное, есть много людей, которых jQuery приучил к плагинам, а фреймворки типа Angular 1, Marionette, Ext, Knockout и пр. – к паттерну MVC.


На мой взгляд, для этих людей подходы React/Redux с фактическим отрицанием MVC кажутся непривычными и неудобными. Однако пользу от виртуального дома они хотят получать. И что греха таить, действительно полноценная экосистема React очень сложна. Angular не сильно проще, да еще и "вещь в себе".


Так в нише между React и Angular появился Vue. Он и с виртуальным домом, и с привычным MVC, и не сильно сложный. Такая буферная зона для небольших проектов, или на период изучения React, или просто чтобы не забивать голову "ерундой". Не думаю, что у него есть шансы сравниться с React, но почитателей он должен был найти.

+2
+3 –1
vintage ,  
React/Redux с фактическим отрицанием MVC

image


image

–1
teux ,  

Fluxxor такой источник непререкаемой информации ) Давайте посмотрим на более авторитетный источник


image


Здесь есть связь store → view, но нет store ← view

+1
+2 –1
vintage ,  

В редаксе эта связь есть (mapStateToProps). В любом случае до "фактического отрицания" тут как до луны.

0
+1 –1
teux ,  

А поконкретнее, пожалуйста. Что есть mapStateToProps? В какую сторону эта связь?

+1
teux ,   * (был изменён)

Ну так не интересно. Я ожидал аргументацию вокруг заведомо ложного тезиса )


mapStateToProps, как следует из названия, передает данные о состоянии приложения (хранится в store) в props компонента. То есть это связь store → view


Вроде мелочь, есть ли обратная связь или нет. Но это то, почему загнулся (т.е. не популярен) упомянутый fluxxor, иже с ним reflux и прочие ранние реализации flux, цеплявшиеся за паттерн MVC.


В отсутствии прямой связи store ← view приложение вынужденно превращается в систему обмена сообщениями. По сути, передача Action в store через dispatch это и есть отправка сообщения тому редьюсеру, который может сообщение обработать.


Видите разницу? Либо визуальный компонент сам что-то меняет в сторе. В этом случае он непременно реализует императивный подход, т.е. напрямую решает конкретную задачу конкретной предметной области. Вьюха перестает быть вьюхой. В ней смешивается уровень визуализации и работы с данными.


Либо в случае react/redux компонент реализует некую событийную модель. Он просто отправляет сообщения "у меня произошло то или другое событие". А потом получает из стора обновленные данные.

–1
+1 –2
TheShock ,  
View запрашивает данные у Store, а не Store решает, какие данные передать View, вот о чем эта стрелочка на диаграмме.

Флакс — самый обычный MVC, но в силу целевой аудитории переименовал понятия, иначе кто бы захотел пользоваться мерзкими корпоративными подходами?

Даже я писал по MVC односторонние потоки за пару лет до фласка, что уж говорить о значительно более умных людях?
0
teux ,  
View запрашивает данные у Store, а не Store решает, какие данные передать View

Протест ) Понятие "запрашивает" означает действие. У действия есть инициатор, и в вашей схеме это view. По факту в Redux все наоборот: view ничего не запрашивает, а только отправляет сообщения о событиях в Redux. Потому во флаксе нет обратной стрелочки.


Флакс — самый обычный MVC...

Тогда давайте подведем под MVC и паттерн глобального неймспейса. В нем можно нарисовать те же стрелочки. Вьюха пишет данные в window.MyStore и читает оттуда же. Чем не MVC? Нет контроллера? Так долго ли вынести пару функций из вьюхи в отдельный модуль.

0
teux ,  

Не знаю, есть ли правильно название у паттерна redux. Я бы охарактеризовал его как "глобальное хранилище с общей шиной сообщений". Это не сильно похоже на MVC

0
staticlab ,  

Конечный автомат же

0
teux ,   * (был изменён)

В принципе, в паттерне MVC модель тоже может слушать события на вьюхе. Но есть у MVC другие негативные черты.


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


Во-вторых, чтобы собрать состояние приложения, надо свести данные всех инстанов всех моделей. Это практически непосильная задача. Кто работал c Redux DevTools, тот понимает удовольствие, когда состояние приложения как на ладони.


В-третьих, рано или поздно возникает необходимость обмениваться данными между моделями. Тут сразу две проблемы:


  1. Как это делать? Передавать ли ссылку на инстанс модели в другую модель (возникает жесткая связанность компонентов). Использовать ли общую шину типа pubsub (связанности нет но взаимодействие непрозрачно).
  2. Менять данные в чужой модели напрямую или через ее хендлеры событий. А вдруг события чужой модели не подходят для этой вьюхи? А прямые изменения — это неконтролируемые хаки.

Это особенности превращаю архитектуру MVC в страшного монстра, развивать и поддерживать который — только время терять. Проще переписать. Конечно, для маленьких приложений надежды на лучшее больше.


Vue от MVC-подхода не ушел. Поэтому, на мой взгляд, это нишевый продукт для маленьких проектов.

0
Riim ,  

У вас какое-то очень странное понимание MVC (ну или у меня). Модель слушающая события въюхи, бизнес логика распределяемая между моделью и въюхой, обмен данными между моделями и тд., видимо меня всю жизнь обманывали рассказывая про какой-то другой MVC.

0
teux ,  

Не знаю, какое у вас, но понимание тех парней, лапшакод которых я не раз разбирал, мне не сильно импонирует.


Это еще одна проблема MVC: в многообразии его трактовок можно потеряться.

0
Riim ,  

То есть вы разбирали лапшакод людей не научившихся готовить MVC, как следствие не научились сами и в результате плохим остался именно MVC?

0
teux ,  

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


При обилии спецификаций MVC понимание зависит от опыта применения. У меня он в целом негативный, причем не на одном фреймворке. Проблемы встречал одни и те же, о чем и написал.


Я считаю, это базовые проблемы паттерна MVC, которые проявляются на практике. В теории, даже прямо здесь, вы наверняка сможете доказать превосходство идеальной модели MVC. Но практика не теория. Вам это известно

0
Riim ,  
Или вы демонстрируете свой единственно правильный взгляд на MVC

мой взгляд полностью совпадает с общепринятым.


Проблемы встречал одни и те же, о чем и написал

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

0
teux ,  
Скажем вы решаете проблему обмена данными между инстансами модели, но зачем?

Потому что одна модель берет данные из одного эндпоинта, другая – из другого. При этом они процессят данные и сохраняют результат. Все хорошо, пока какой-то новой вьюхе не потребуются данные обоих эндпоинтов (какая капризная).


Что делать? Создать новые интсансы двух моделей и подключить к капризной вьюхе? Но у нас уже есть эти инстансы и возникнут дубли запросов, память будет расходоваться вдвойне.


Значит надо подключить существующие инстансы к этой вьюхе, значит делать хранилище инстансов.


А если капризная вьюха начнет менять данные в общих моделях, останутся ли данные консистентными для других вьюх?


А если другие вьюхи отмонтированы и делают destroy моделей, что произойдет с остальными вьюхами, подключеным к тем же инстансам?


А если вьюха не дестроит модель, то кто это делает?


А если вьюха отмонтирована, снова подмонтирована, получила живой инстанс модели и пытается провести начальную инициализацию...


… если, если. И получается безопаснее не переиспользовать инстансы моделей.


Тогда остается дублирование или хитрые заходы сбоку в существующие инстансы моделей, чтобы капризная вьюха получила/поменяла данные. Отсюда возникает лапша.


Повторяю, в мире идельной архитектуры такая схема невозможна. Но почему-то плохие парни в жизни об этом не знают )


Вы скажете "Так ведь можно попросить бек сделать подходящий эндпоинт для капризной вьюхи". Согласен, часто так и делается. Но это уже архитектурная связанность даже не на уровне компонентов, а на уровне API

0
Riim ,  
пока какой-то новой вьюхе не потребуются данные обоих эндпоинтов (какая капризная).

так в чём проблема-то? Вполне нормально когда въюха показывает данные нескольких моделей. Может данные зависимы друг от друга?

0
teux ,  

Важно, сколько усилий тратится на решение проблем с подходом MVC и Reac/Redux, насколько эффективно получается решение изначально.


За функциональной сложностью растет сложность архитектуры, отладки, поддержки. При использовании MVC сложность растет быстрее, чем в случае React/Redux.


В теории мы можем разобрать любой спорный случай MVC, и вы покажете, что было изначально сделано не так, почему возникли проблемы потом. Но на деле невозможно представить всю архитектуру приложения заранее. Очень может быть, что казавшееся правильным решение потом потребовало хаков.


Бывает так в React/Redux? Конечно. Но вопрос в трудоемкости рефакторинга. Когда изначально все данные хранятся в одном месте, разработчик сразу понимает, что общие данные надо хранить в нормализованном виде, не делать кастомный препроцессинг под потребности конкретной вьюхи. Если такая обработка нужна, она выносится в компонент-контейнер (обертка над вьюхой). Применяются селекторы для оптимизации производительности. Код получается гранулярным и тестируемым.


И такой подход универсален в React/Redux. Один раз освоить, и можно использовать для решения любой задачи. В MVС, по моему опыту, как только получаешь гладкую архитектуру, как появляется новая задача, которая вносит противоречия, и нужно перестраивать отдельные модели и вьюхи.


Поэтому MVC для меня лично (никому не навязываю) — это антипаттерн в отношении архитектуры фронта.

0
teux ,   * (был изменён)

Еще добавлю, что когда-то данные хранились в глобальном нейспейсе. Это было всем удобно и привычно. Потом взошла звезда MVC, данные растащили по моделям. Появились неудобства в интроспекции общего состояния приложения.


Redux, по-сути, вернул подход единого хранилища. Данные хранятся как раньше — в едином дереве. Появились прекрасные инструменты итроспекции типа Redux DevTools.

0
vintage ,   * (был изменён)

И где вы тут видите неудобства интроспекции?

0
teux ,   * (был изменён)
А как вам такая картинка (Redux DevTools визуализирует стейт)?

+1
vintage ,   * (был изменён)

Эти красивые картинки бесполезны при числе моделей более 100.

0
teux ,  
Ахм… ну ладно, закончим на магическом числе 100 )
0
JSmitty ,  
А vuex вы во внимание не принимаете? Он, конечно, сильно проще чем Redux — но тоже местами жизнь сильно упрощает.
+7
CodeViking ,  
Мне одному кажется что данный холивар бессмысленный?
0
SbWereWolf ,  
Видимо всем всё понятно и ни кто примеров из статьи не запускал, у меня второй пример не взлетел. Был список, то есть элементы , но у элементов не было .InnerText.
Я попытался на авось поменять код тут и там — не помогло, в консольке был варнинг со ссылкой https://vuejs.org/v2/guide/list.html#key и вот там в примере вместо «todo.text» было просто «todo», я подставил как в примере и у меня заработало.
<div id="app">
  <ol>
    <todo-item v-for="item in list" :todo="item"></todo-item>
  </ol>
</div>

<script src="https://unpkg.com/vue"></script>
<script>
  Vue.component('todo-item', {
    props: ['todo'],
    template: '<li>{{ todo }}</li>'
  });
  
  new Vue({
    el: '#app',
    data: {
      list: [ 'first item',  'second item']
    }
  });
</script>

вопрос к автору, почему не работает todo.text? я что то упустил?
0
c01nd01r ,  
В проперти todo компонента <todo-item> приходит item — элемент массива list. Никого свойства text у него нет.
0
rboots ,  
Исправил
0
+2 –2
Valery4 ,  
Дочитал до момента, чем плох TypeScript и дальше не стал читать. Мне кажется плохим тоном преподносить даже что-то хорошее, за счёт очернения другого, которое тут ещё и не к месту приплели.
В общем статья для меня возымела противоположный эффект, к моей симпатии к Vue.js и потенциальным желанием как нибудь попробовать, теперь осадочек мутный.
+4
ArVaganov ,   * (был изменён)
Ребята давайте будем откровенны, статья – так себе и несет много необоснованного хейта. Человек даже 2 месяца не проработал на фреймворке и на волне хайпа просто набрал текст и выложил его сюда. Не нужно выплескивать негатив в комментарии и серьезно тут устраивать холивар.
У меня уже есть небольшой опыт использования Вью, мы с командой пишем проект на Laravel + Vue, (до этого не знал ни одного фронтенд фреймворка).
Могу вам сообщить действительно отличное преимущество у Вью – это возможность включать его в проект точечно. Это очень полезно когда нужно переписывать и улучшать легаси код. Подключил на страничке скрипт весом несколько килобайт, написал парочку vue компонентов, и вот уже то — что на JQuerry и ванилле было лапшой навешано (и невозможно поддерживать) теперь аккуратно, компактно лежит, реактивное, а главное при этом еще и работает быстро.
Лично я хочу делать карьеру именно во фронтенде, поэтому параллельно работе с вью учу и реакт. И я хочу вам сказать, что у этих двух фреймворков просто разный подход к рендеренгу шаблонов, всю бизнес логику можно написать на них обоих. И по сути конечный результат зависит от прослойки между стулом и монитором без разницы при помощи чего вы будете создавать свой код.
Теоретически большие одностраничные приложения можно делать как с использованием Vue, так и с Реактом. Поддерживать легаси, писать какую-то небольшую динамику на странице проще однозначно на Vue. Порог входа очень легкий и документация классная! Так что не бойтесь, пробуйте. В любом случае от «лишних знаний» хуже не станет, т.к. и вью и реакт нужны для специализации по фронту.
0
+1 –1
rboots ,  
У вас логическая ошибка. 2 месяца я проработал на Vue, и до этого лет 5 на Angular, а так же 15 лет во фронтенде в целом. По идее, раз так, я наоборот должен был бы хейтить Vue, так как старые технологии всегда кажутся более понятными, а новые вызывают много непонимания, но здесь наоборот. Хейтить Ангуляр я имею полное право, точнее не хейтить, а аргументированно указывать на недостатки. По Реакту мне подсказали, что компоненты можно создавать проще, если отключить JSX, в этом я не прав, но даже с учётом этого их размер всё равно больше, чем на Vue, поэтому моих знаний React вполне хватило для обоснованной аргументации.
Давайте будет откровенны, ваш пост несёт в себе много много необоснованного хейта, и я только что пояснил, в чём именно. Ваш же пост такой агрументации не содержит, только предположения о человеке, второй снизу уровень на пирамиде Грэма. Поэтому повышайте культуру общения, и удачи вам с вашими собственными статьями.
–1
rboots ,  
Если бы прочитали одно предложение дальше — узнали бы, что ничем. А теперь у вас осадочек мутный. Мне кажется плохим тоном критиковать то, что не прочитал.
+1
Fragster ,  
Мне только одно непонятно, зачем в vuex выделили мутации и запретили менять state из action напрямую?
0
JSmitty ,  
Action — это такая калька с actionCreator-ов в React (точнее redux-thunk по сути), соответственно мутации как бы эквивалентны action+reducer. Дизайн делался с оглядкой на Flux/Redux, и это видно во всём.
0
Fragster ,   * (был изменён)
Общий смысл мне понятен. Но непонятно, почему в компоненте я пишу this.var = value и всё работает, а в vuex я вынужден для каждой переменной store писать функцию по установке значения и в action'ах писать context.commit('setVar', value)?
0
indestructable ,  

Вью — это то, каким должен был быть первый Ангуляр. С ним легко начать, и легко делать простые приложения, но для сложных вещей его DSL недостаточно гибкий.


Вью позволяет использовать привычный и более легко воспринимаемый компонентный подход со стейтфул компонентами.


Реакт требует пересмотра самого подхода к проектированию. Использовать стейтфул компоненты можно, но Реакт этого не поощряет (я имею ввиду не стейт самого компонента, а бизнес данные в стейте).


С Реактом и, например, редаксом, тяжело начинать (особенно первые несколько раз), потому что подходы к архитектуре кардинально отличаются от подходов, например, Ангуляра.


Одно только редактирование форм после Ангуляра может заставить человека бросить Реакт и вернуться к Ангуляру :)


Однако, сложные вещи делать проще, расширять приложение проще, приложение более гибкое, и изменения применять проще.


Я приведу свой опыт с Реактом — я Реакт практически не замечаю. Потому что вся сложность — она в app state. Компоненты разрабатывать проще — потому что думаешь про функционал самого компонента — какие свойства ему нужны и как они повлияют на отображение компонента.


Да, этот подход можно использовать и в Ангуляре — но стал бы я его использовать там, если бы не попробовал раньше? Уверен, что нет, ведь проще сделать двусторонний байндинг, а не разнести потоки данных.

0
vintage ,  
проще сделать двусторонний байндинг, а не разнести потоки данных

Одно другому не мешает, вполне можно разносить потоки данных и через двусторонний биндинг.

0
dos ,   * (был изменён)
Вопрос к знатокам React/Vue — если бы была задача реализовать компонент грида, обладающего хотя бы основными возможностями грида от ExtJS то на каком бы из фреймворков бы вы это делали и почему?
0
raveclassic ,  

Вы понимаете, что только подливаете маслеца в огонь? :)
Половина скажет React, половина — Vue.

0
Starche ,  
Я б делал на втором ангуляре. Просто потому что я уже его делал на втором ангуляре. Сортировка, фильтрация, нормальная пагинация/бесконечный скролл, прибитая к верху шапка, подгрузка с сервера/подготовленные заранее данные, кастомно оформленный скроллбар (перетащил логику из nanoscroller.js), выделение чекбоксами. Мне пока не были нужны фичи типа группировки строк, но я представляю, что мне надо дописать в существующий код, чтобы их получить. И это будет не очень много возни.
Ну а ячейки я могу оформить как угодно, потому что это пишется прямо в шаблоне, могу хоть компоненту графика туда подгрузить, хоть редактируемую ячейку сделать.
Аналогично и с оформлением шапки/футера: любые кнопки можно вкинуть, это не проблема.
Ну и количество кода, конечно, смехотворное на это уходит.
–1
+1 –2
jakobz ,  
Писать что-то серьезное на нетипизированном языке — нельзя. Как следствие, все фреймворки со своими шаблонами — сразу выкидываются в помойку, без попыток в них разобраться.
0
staticlab ,  

А как же TypeScript?

0
jakobz ,  
Речь про DSL шаблонов, в котором строгой типизации нет, и как ее приделать — непонятно.
0
JSmitty ,  
Пишите рендер-функции, и будет типизация как и в остальном коде.
0
vintage ,  

Кроме тех, что компилируют шаблоны в тайпскрипт.

0
VolCh ,  
JSX — это XML по сути со вставками JS/JS+Flow Type/ Typescript (то, что лично пробовал) со всеми вытекающими.
0
JSmitty ,  
Сам фреймворк, AFAIK, написан с использованием Flow. Для желающих есть поддержка Typescript от коммьюнити.
0
raveclassic ,  

Речь идет не о фреймворке, а о проектах его использующих.

–1
+2 –3
G-M-A-X ,  
Я хз, может я баран.
Но мне проще писать на jQuery как я хочу, а не вникать в эти новые веяния, которые быстро умирают, в отличии.
При этом учитываем, что:
а) старые ресурсы нету особого смысла переписывать на что-то другое
б) есть куча заготовок, которые упрощают жизнь

В чем их преимущество над jQuery? :)
+3
+4 –1
TimTowdy ,  
В том, что разваливаться от сложности ваш проект на jQuery начнет через 3 месяца, на React через 6, а на Vue через 9.
<sarcasm>А на Angular — еще до начала проекта.</sarcasm>
0
kellas ,  
Меня удивляет что все как-то обходят стороной Riotjs
+1
+2 –1
Fen1kz ,  

Давно присматриваюсь к vue, но статья вообще не убедила. Автор, прости, она, мягко говоря ужасна.


Чем? Цель этой статьи — убедить использовать "лучший фреймворк на 2017 год". Как она убеждает?


Я прошелся по статье и собрал все плюсы vue которые вы написали


Это действительно весь код, который вам нужен, это не шутка. Вы можете прямо сейчас скопировать его в редактор, сохранить как something.html и он будет работать.

Что бть? Серьезно, не шутите? Давайте в автожурналах писать "Хендай — лучшая машина 2017" и первым пунктом там ставить "у нее пепельница вынимается быстрее чем в других машинах". И это первый мать его реальный плюс. Не надо так, пожалуйста.


Получилось чуть подлиннее, но у нас здесь custom controls. Custom controls в 20 строчках кода, Карл! При этом сам компонент занял всего 4 строчки. Что это значит на практике: что вы можете делить свой код на компоненты настолько мелко, насколько вам хочется, с минимальными издержками.
Если в React создание отдельного компонента — целая история, в завязкой, кульминацией и развязкой, то в Vue это просто несколько секунд. И дело не в этих секундах, а в том, что с большим количеством компонентов у вас будут слабее зависимости и меньше багов.

I see what you did there… Вы думаете что лучший фреймворк как UI — чем меньше тем лучше? Ну, ваше право.
В Реакте такой компонент занимает 1 строчку и 91 символ (я видел вы в комментах считаете и символы):
export default ({todo}) => (<li>{todo}</li>)


Это синтетический пример компонента, но в реальных Vue.js раскрывает себя ещё лучше. Мы можем, например:

Ну, неужели пошли какие-то реальные плюсы?


вынести весь код компонента в отдельный *.vue файл, включая html, css и javascript
использовать css-препроцессоры прямо в коде файле компонента, просто указав lang=«scss» или другое
использовать любые глобальные объекты или получать объекты через import (в React, кажется, на это есть ограничения)

использовать компоненты только внутри других определённых компонентов, без объявления в глобальной области видимости. Использовать компонент под другим именем, без изменения самого компонента (удобно в случае коллизии имён сторонних компонентов)

Ну как бы это стандартный import todo from


и многое другое. Для большинства этих функций нужно подключать сборщик (в документации описан webpack), однако вам дают выбор, использовать Vue на 10%, 50% или на все 100%.

Воу, воу, вы уже сказали что первый и главный плюс, цитирую "Это действительно весь код, который вам нужен, это не шутка." То есть в начале сказали что отсутствие сборщиков — плюс к vue, а сейчас — присутствие сборщика — плюс к vue?


Vue.prototype, Карл!

Карл, ты когда пишешь в плюсах "не засирает глобальную область", ты как бы в прототип-то не лезь, Карл.


Зачем отделять React от зависимостей, если внутри компании он без зависимостей не используется?

Фейспалм.


В общем, я расстроен, у меня были такие надежды на vue и на вашу статью (из-за провокационного заголовка), а получился какой-то hello world =\

0
VladVR ,  
export default ({todo}) => (<li>{todo}</li>)

И я об этом же написал. За парой нюансов — мне не нравятся анонимные функции, в стектрейсе если что хочется видеть имя, и я не использую export default, потому что навигация в VsCode не так срабатывает. Чтобы перейти на имплементацию надо два клика вместо одного. И я готов ради таких удобств жертвовать краткостью. Что сразу же подразумевает, что краткость для меня — не первый приоритет.
В ангуляре же(что первый, что второй/четвертый), как и во Vue(если не ошибаюсь), речи про навигацию вообще не идет. нужно скопипастить строчку и ctrl-shift-f.
0
raveclassic ,  

Кстати, если совместить именованные экспорты и TS, то большинство IDE/редакторов смогут помочь автоимпортом.

0
Fen1kz ,  

На самом деле плевать сколько там строчек, лично для меня, в отличие от автора, это будет приятный бонус, нежели один из основных пунктов что этот фреймворк — "лучший в 2017"

+1
VladVR ,  
«Просто» сделать в 1000 раз сложнее, чем «сложно».
«Простота» здесь относится к чему? Сложилось впечатление, что Карлу пытались объяснить, что простота = количество строк кода.
вот это
Vue.component('todo-item', {
    props: ['todo'],
    template: '<li>{{ todo }}</li>'
  });

на реакте пишется вот так
export function TodoItem({todo}){
    return <li>{todo}</li>;
}

Существенно проще, не правда ли?

Если говорить о простоте в терминах «понять как оно работает», и «понять как на этом писать», то получается, что у реакта jsx являет собой некоторую сложность, конечно, но сложность несравнимо меньшая, чем некоторый template engine, в котором, как и в ангуляре, свой ужасный микро-язык (я вот об этом v-for=«item in list», не хватает только любимого хака track by $index), с кучей всяких деталей и конвенций, которые нельзя понять, можно только простить. И вот мы все успешно это изучили, а теперь с приходом второго ангуляра это надо как то из головы выбросить и начать вталкивать другой микро-язык, который стал еще хуже(box-of-bananas-syntax [()] ). И еще одна альтернатива, которая взяла из ангуляра худшее, и переиначила на свой лад ради более краткого синтаксиса — просто идет в топку.

И да, не стоило «отвергать» typescript. На типизованном языке настолько проще поддерживать код, что на чистый js возвращаться уже не хочется. Вот тут, кстати я посмотрю, некоторые люди ui фреймворки отвергают, и пишут на jquery. Какой уж там typescript.
+1
VolCh ,  
0
franzose ,  

Во Vue можно использовать "локальные" компоненты. Будет примерно то же самое:


export default {
    template: '<li>{{something}}</li>'
}
+3
sitev_ru ,  
На данный момент не использую для веба ни Vue, ни Angular, ни React, обхожусь пока Javascript/JQuery). Поэтому сильно не бейте). Решил попробывать Ваш примерчик.

Меня напрягает сразу же следующее: появляется надпись {{ message }}, которая держится целую секунду! Потом надпись меняется на «Hello Vue!»

Как сделать, чтобы сразу выводилось «Hello Vue!»?
+1
vintage ,  

Стандартный костыль ко кривому дизайну: https://vuejs.org/v2/api/#v-cloak

+1
TimTowdy ,  
Не нужно дезинформировать людей. К кривому дизайну это отношения не имеет. Эта проблема возникает только в случае когда шаблон берется из DOM, а не из строки, что не рекомендуется делать т.к. браузер может зарезать некоторые тэги. Подозреваю что возможность брать шаблон из DOM сделана исключительно для упрощения туториала, в продакшене это никем не используется.

sitev_ru
Решается проблема очень просто: вместо того чтоб шаблон брать из DOM, его стоит передавать в компонент напрямую через template (передавать туда либо строку шаблона, либо #id &ltscript> тэга с шаблоном).
0
vintage ,  

Даже получение шаблонов из дом можно сделать куда прямее.

0
TimTowdy ,  
Например как? Мне правда, очень интересно.
+1
vintage ,   * (был изменён)
0
restyler ,  
и что, по-вашему, Vue так не умеет? :) https://jsfiddle.net/coligo/fjpqz387/
–1
vintage ,   * (был изменён)

Речь не о том, что он умеет, а о том, что позволяет и рекомендует и для чего даже везёт с собой костыли.

0
TimTowdy ,  
Речь о том, что вы не разобрались во Vue, но спешите его критиковать.
Во Vue есть два понятия: mount element (el) — элемент, внутри которого будет рендериться ваше Vue приложение, и template — собственно шаблон разметки вашего приложения.
Задача Vue — реактивно рендерить шаблон внутри mount element.

В исключительном случае, когда приложению передан только mount element, без template, Vue делает следующее:
1. генерирует template из DOM-содержимого mount element
2. замещает содержимое mount element отрендеренным template
Именно в этом причина проблемы sitev_ru.

Элемент <template> ничем не помогает: Взять шаблон из конечно него можно, а вот использовать его как mount element, по понятным причинам — нет.

Ну и судя по тому, что в предоставленной вами ссылке стоит No Support у IE, и вопрос — у части мобильных браузеров, я не вижу ничего удивительного в том, что Vue нигде не рекомендует использовать такой способ передачи шаблона.
0
vintage ,  

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


В чём проблема преобразовать <template> в <script type="template"> поддерживающийся всеми браузерами?

0
TimTowdy ,  
Кто будет преобразовывать? Vue работает в том числе и без транспиляторов.
Да и зачем? Если можно сразу использовать <script type=template>?
Вы свою аргументацию вообще слышите?
«логика кривая потому что этого вообще не должно быть»
«вместо <script> нужно использовать <template> и преобразовывать его в <script>»
0
vintage ,  

Ну пишите вручную <script type="template"> какие проблемы?
Логика кривая потому, что отображение неинтерполированного шаблона никому не нужно. Вообще никому. Но в документации мы видим именно такие примеры. От чего каждый разработчик ходит по одним и тем же граблям.

0
TimTowdy ,  
Так я и пишу <script>, это вы зачем-то рассказываете что «правильнее» использовать <template>, хотя потом выясняется что это не так.

В документации этот случай описывается неоднократно. Но я согласен что магия двойного использования mount element скорее вредит новичкам, чем помогает. Предполагаю что это сделано по большей части для маркетинга (легче рекламировать Vue). Лично мне эта магия не нравится, но жить совсем не мешает (я всегда указываю template). Разводить из-за этого истерику и кричать о «костылях» я точно не собираюсь.
0
JSmitty ,  
Вариант такой:
<div id="app"><span v-text="message"></span></div>

А вообще проблема типовая, для Angular.js 1 даже название придумали — FUC (Flash of Uncompiled Content). И да, в случае полноценно собираемого SPA приложения проблемы не будет.
0
Akuma ,  
Ахаха, я все ждал когда появится этот комментарий, но к сожалению уехал.
Вернулся — а тут оно самое :)

Добро пожаловать в мир Vue (Angular 2017).
Совсем скоро вы познакомитесь с «track by $index» и другими модными костылями :)
0
erlyvideo ,  
Если в React создание отдельного компонента — целая история, с завязкой, кульминацией и развязкой, то в Vue это просто несколько секунд.


ну вы серьезно? Не, так не надо продавать то, что вам нравится.
+2
riky ,  
vue выстрелит за счет низкого порога входа. его киллер фича в этом.
думаю скоро его будут пихать как jquery на каждый сайт.
0
serf ,  

Он еще довольно легкий по размеру и с хорошей документацией.

–1
KirEv ,  
не холивара ради, но почему не использовать технологию\язык исходя из:
а) я владею и разбираюсь
б) решение быстрее и удобнее

Посмотрел пример модального окна: https://vuejs.org/v2/examples/modal.html

Чтобы сделать подобное на яквери:
1. подключить jquery ui
2. написать 4 html-тега для окошка
3. и одна строчка js-кода, одна строчка Карл!

Мне не понятно в каком месте vuejs что упрощает.

Но самое интересное начнется при необходимости нетривиального решения.
0
JSmitty ,   * (был изменён)
Вы сравниваете несравнимое. Попробуйте реализовать этот контрол на чистом JS + HTML.
Ну и для полноты — есть такая библиотека, vueStrap, там модалка реализуется фактически в 0 строк JS:
<modal v-model="show" @ok="show = false">
  Текст в модалке
</modal>
<button @click="show = true">Открыть модалку</button>
0
Areso ,  
https://unpkg.com/vue
259 килобайт
+1
staticlab ,  
0
Fragster ,  
vue.common.esm.js 50кб gzip
vue.esm.js 70кб gzip (это если зачем-то на клиенте нужно шаблоны «компилировать»)
0
Areso ,  
Вы в страницу в соурс скрипта будете gzip вставлять? Это работает?
Просто я прошелся по ссылке на скрипт из примера и слегка огорчился.
Примерно также меня огорчает jQuery UI в половину мегабайта ради настраиваемых надписей на модальном окне с предупреждением.
0
staticlab ,  

В любом случае сервер скорее всего передаст и html, и js гзипованными.

0
TimTowdy ,  
Вы сейчас шутите? Посмотрите на заголовки HTTP-запроса вашего браузера. «Accept-Encoding: gzip» ни о чем не говорит?
Пожатый Vue весит ~20KB, в 2 раза меньше React и в 5-6 раз меньше Angular.
https://gist.github.com/Restuta/cda69e50a853aa64912d
0
teux ,  
Хром недавно поддержал параметр ?react_perf и теперь можно профилировать react-компонеты на Timeline.
Интересно, будет в хром параметр vue_perf?
+1
vintage ,  

Хром тут ни при чём, это возможность самой библиотеки.

0
teux ,  
Да, вы правы. Я не точно выразился. Просто порадовался новому удобству в Хроме
0
alek0585 ,  
Статья ни о чем, конечно, но и комментаторы сплошь гении. Так может быть кто-нибудь сможет ответить на вопрос заголовка статьи?
+2
TimTowdy ,  
Почему Vue.js — лучший фреймворк для front-end разработки на 2017 год?
Просто потому что Vue моложе и воспользовался возможностью учесть ошибки своих предшественников. Взял от них лучшее, избавился от худшего. Получилось крайне удачно.
0
indestructable ,  

Вынесу вопрос в корневой комментарий.


При чтении комментариев неоднократно натыкался на утверждение, что Vue использует virtual DOM, и на самом деле, неявно работает похожим на React (а точнее, на JSX) образом, а именно преобразует шаблон компонента в построение виртуального дерева, и на самом деле шаблоны можно не использовать, а можно использовать render функции (то есть практически аналог функции render() в Реакте, как я понял).


У меня в связи с этим несколько вопросов:


  1. Правда ли это вообще?
  2. Есть ли где об этом почитать, статью или раздел документации?
  3. Значит ли это, что шаблоны Вью нельзя расширить новыми атрибутами, то есть там нет аналога директив Ангуляра.
  4. Работают ли паттерны функциональной композиции применительно ко Вью, например, компоненты высшего порядка?

Спасибо

0
staticlab ,   * (был изменён)

Не специалист во Vue, но Virtual DOM в нём действительно есть: https://github.com/vuejs/vue/blob/dev/src/core/vdom/patch.js


Это как раз то, что автор данной статьи предлагал легко написать в 50 строк.

0
indestructable ,  

Частично отвечу на свой вопрос:


https://vuejs.org/v2/guide/render-function.html


Действительно, вместо шаблона можно использовать функцию, которая возвращает виртуальный DOM, есть даже JSX для Vue (сюрприз-сюрприз). Шаблоны компилируются в нее же.


Судя по беглому изучению документации, все это очень сильно завязано на внутреннюю кухню Вью, элегантности Реакта (все есть или функция или ее параметры, все: свойства, события, дочерние элементы (которые могут быть опять же чем угодно)) здесь нету.


Меня больше удивило другое: во Вью присутствуют элементы самых разных концепций: change tracking + dependency graph, вычисляемые свойства со встроенной мемоизацией (тут я могу ошибаться), встроенная шина сообщений.


Делается это, насколько я понимаю, для оптимизации генерации virtual DOM (зачем еще это может понадобиться, ума не приложу).


Если проводить аналогии с Реактом, то Вью — это Реакт + MobX для стейт менеджмента локальных данных компонента + свой язык шаблонов для описания рендер-функций, более близкий к HTML, чем JSX.


Для себя я сделал предварительные выводы:


  • тот, кто говорит что Вью проще Реакта — говорит в первую очередь о языке шаблонов (и противопоставляя его JSX). Внутренняя кухня имеет на порядок больше концепций, чем Реакт, и изучать ее гораздо сложнее.
    Попробуйте, не заглядывая в доку, сказать, что делает этот кусок кода:


    render: function (createElement) {
    var self = this
    return createElement('input', {
    domProps: {
      value: self.value
    },
    on: {
      input: function (event) {
        self.value = event.target.value
        self.$emit('input', event.target.value) // Все понятно, но зачем это???
      }
    }
    })
    }

    (создает двустороннюю привязку)


  • Оптимизация рендеринга многоуровневая — как по данным, так и по виртуальному ДОМ. Вью скорее всего будет быстрее. Однако нужно помнить подводные камни каждой оптимизации, слишком легко их сломать неправильным использованием.
  • Язык шаблонов Вью — это его действительно сильная сторона, это не Ангуляр с произвольно расширяемым набором атрибутов есть кастомные директивы. Однако, для Реакта ничего не мешает сделать то же самое, первый же найденный пример — http://wix.github.io/react-templates/
+1
TimTowdy ,  
  1. Да, начиная с версии 2, Vue под капотом использует VirtualDOM.
  2. Например здесь: render()
  3. Custom directives есть.
  4. Функциональная композиция это возможность JS, а не фича какого-то отдельного фреймворка. Во Vue тоже можно ее использовать, хотя в документации это почти не упоминается. Кстати, часть потребностей в HOC покрывается слотами.
0
indestructable ,   * (был изменён)

Спасибо за ответ.


1, 2 — сам разобрался


3. Зачем они нужны? Работают ли они с виртуальным ДОМ или с реальным? Правильно ли я понимаю, что директивы — это способ работы с ДОМ элементами?


4. Можно пример функциональной композиции ангуляровской директивы или компонента?

0
TimTowdy ,  
3. Предназначены для работы с реальным ДОМ, но доступ к виртуальному есть.
4. С ангуляром у меня отношения не сложились, поэтому пример не приведу. Композицию контента можно посмотреть в ссылке про слоты. Обычно композицию компонентов во Vue все же делают более стандартными extends/mixins. Но функциональная композиция вполне возможна, просто потому что она не привязана к какому-то фреймворку. Хотя до идиоматичности во Vue ей конечно пока далеко.
0
indestructable ,  

А как считаете, помимо языка шаблонов (который можно прикрутить и к Реакту), и скорости (которая достигается через observable data, и может быть использована в Реакте через сторонние либы), какие преимущества у Вью?


На мой неискушенный взгляд в нем слишком много концепций со своими ограничениями: наблюдаемые данные, шина сообщений, ограничение на вычисляемые данные в шаблоне, встроенная мемоизация — нужно ли это? Не приводит ли это к странным неинтуитивным багам типа когда не вызвал apply в Ангуляре, или явно борешь ленивость логических выражений, чтобы затрекались зависимости в Нокауте?

+1
vintage ,  
может быть использована в Реакте через сторонние либы

Боюсь там всё не так просто. Чтобы реакт увидел изменения нужно в любом случае перередеривать всех предков до корня, что может быть весьма не быстро.


явно борешь ленивость логических выражений, чтобы затрекались зависимости в Нокауте

Это вы о чём?

0
indestructable ,  

В Нокауте зависимости между observable трекаются так:


  • начинается вызов observable a
  • все другие observable/computed, вызванные выше по стеку (во время выполнения а), считаются зависимостями а. При их изменении а считается измененным.

Проблема заключается в следующем. Пусть есть observable (вернее, computed, в терминологии KnockoutJS), который вычисляется следующим образом:


areAllTrue: ko.computed(function areAllTrue() {
    return this.a() && this.b() && this.c();
})

Для того, чтобы a, b и c были помечены как зависимости, они должны быть выполнены при выполнении areAllTrue. Однако, если a() === false, то b() и c() вызваны не будут (т.к. результат логического выражения уже известен), и, значит, они не будут помечены как зависимости, а значит, не areAllValid не будет пересчитан при изменении b() или c().


В общем-то, это не большая проблема, если фреймворк строит граф зависимостей при каждом вызове (а не один раз при первом).

0
vintage ,  

Так нокаут при каждом вызове и трекает же. С чем вы там боретесь-то?

0
VladVR ,  
Если говорить о проблемах в нокауте, то мы натолкнулись вот на такую:
есть массив объектов, у которых observable свойство isChecked. Мы делаем фичу selectAll. Чтобы отобразить значение чекбокса над гридом пишем примерно такой код
isChecked = ko.computed( () => return !items.some(item => !item.isChecked()))

далее по нажатию на этот чекбокс нужно все элементы поставить в новое значение чекбокса над гридом
onChange = (newValue) => items.forEach(item => item.isChecked(newValue))

при изменении каждого из этих observable пересчитывается вышеозначенный computed, то есть мы получили на пустом месте O(n в квадрате)
+1
vintage ,   * (был изменён)

В нокаут уже давно завезли отложенное обновление, но по умолчанию оно выключено для совместимости.

0
TimTowdy ,  
Не думаю что у Vue есть хоть одно серьезное преимущество в плане каких-то уникальных фич. Многие расхваливают слоты, но это конечно далеко не killer-фича.

Для меня Vue это просто SPA-framework с хорошим интерфейсом. Умеет абсолютно все то же, что и остальные фреймворки, но делает это чуточку лучше.
Переписывать существующие React/Angular приложения на Vue смысла не вижу. Как и не вижу смысла начинать новое приложение на React, если есть Vue. Как чтение, так и написание кода приложений лично мне кажется более интуитивным по сравнению с React. Когда я смотрю на код React-приложений, у меня постоянно возникает мысль «ну неужели это нельзя было сделать лучше?!». Vue в этом плане как глоток свежего воздуха.

Подводные камни конечно встречаются и внутренняя магия может дать о себе знать. Одно только отслеживание зависимостей computed свойств чего стоит (элегантное, но жутко неочевидное решение). Новички вероятно столкнутся с проблемами, вызванными непониманием внутренностей. Но это будет в любом фреймворке. C другой стороны сообщения об ошибках и warnings у Vue очень информативные.

Часть проблем вызвана недостатками самого языка, например в Javascript до сих пор невозможно сделать getter/setter/deleter на индексы (даже с учетом транспиляторов, спасибо IE). Т.е. возникает такая ситуация:
this.a = ['test1'] // реактивно
this.a[0] = 'test2' // не реактивно


В целом, неинтуитивные баги конечно встречаются, но (субъективно) реже чем в других фреймворках. YMMV.
–1
vintage ,  
Умеет абсолютно все то же, что и остальные фреймворки,

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

0
franzose ,  

Немного странные претензии.


  1. Детальная кастомизация зависит от того, каким образом сам компонент написан и позволяет ли он сам себя кастомизировать.
  2. Автоматическая вставка индикатора — зачем именно автоматическая?
  3. Падать из-за сбойного компонента. А как по-другому, если нормальная работа приложения невозможна?
  4. Локализацию можно сделать самостоятельно.
0
vintage ,  
  1. О том и речь, что зависит. А есть фреймворки, в которых не зависит.
  2. А зачем она ручная? Это одинаковый код в куче мест.
  3. Почему это невозможна? Упал какой-то блок на странице — ну и чёрт с ним, нарисуй грустный смайлик вместо него, но не белый экран же вместо всего приложения.
  4. Можно. Много чего можно. Зачем вам вообще фреймворк с такой любовью делать всё самостоятельно? :-)

Ну и знаете, аргумент "этого нет в моём фреймворке, поэтому это не нужно, а значит в нём есть всё, что нужно" — так себе.

0
franzose ,  
  1. Делаем кастомный компонент — будет полуавтоматическая :)
  2. Будет повод как можно быстрее эту ошибку исправить, а не забить до лучших времен.

Ну и знаете, аргумент "этого нет в моём фреймворке, поэтому это не нужно, а значит в нём есть всё, что нужно" — так себе.
Я этим отнюдь не руководствуюсь)
0
vintage ,  
  1. Мало сделать компонент, в большинстве фреймворков нужно ещё создать развесистый конфиг и написать кучу кода по его интерпретации.


  2. Вы про какую ошибку?
0
franzose ,  

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

0
vintage ,  

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

0
franzose ,  

В таком случае я бы просто заменил компонент на другой. Ну, а если в наличии ничего более адекватного нет, то либо сделал бы pull request авторам, либо своё б написал на худой конец.

0
vintage ,  

Суть не в том, какой плохой компонент, а в том, как фреймворк реагирует на исключительные ситуации.

0
raveclassic ,  

Кстати в React 16 наконец-то запилили адекватный механизм обработки ошибок

0
franzose ,  

Любой фреймворк выдаст вам ошибку и упадёт. Серверные поступают ровно так же.

0
vintage ,   * (был изменён)
+1
bano-notit ,  

-_-
А ещё какой-нибудь пример можно?

0
vintage ,   * (был изменён)

А этот чем не нравится? Впрочем, пожалуйста: http://mol.js.org/#demo=mol_app_habhub_demo/gist=21423554

0
raveclassic ,  

Мне бы вашу невозмутимость :)

+1
bano-notit ,   * (был изменён)

Просто Эту фичу Вашего фреймворка Вы уже Много где рекламировали, а я бы хотел узнать, какие ещё фреймворки там умеют.

–1
vintage ,  

Мне о таких не известно. Скорее всего больше никакие.

0
lega ,  
В alight можно прикрутить обработку ошибок, можно вывести трейс, скоуп, обработать проблемный элемент и т.п. пример.
0
vintage ,  

К сожалению работает не везде: https://jsfiddle.net/gkrzztrb/4/
Всё приложение тем не менее не падает, да. Но без реактивности оно в общем случае не сможет восстановить свою работу и будет глючить до перезагрузки, даже если причина исключения устранена.

0
franzose ,  

В итоге всё равно ошибки необходимо будет обрабатывать самостоятельно.

0
lega ,  
Работает везде (где нужно), просто баги в разных местах могут иметь нюансы, напрмер в вашем примере ошибка возникает до «объявления» обработчика, а обрабочик дожен быть привязан заранее (до ошибки) если нужно что-б он был вызван, поправил пример

Но даже без обработчика, все «приложение» работает за исключением этого багового биндинга на кнопке.
0
vintage ,   * (был изменён)
$scan, error in expression: {{xx}}

Классный стектрейс, сразу понятно, где ошибка :-)


Но даже без обработчика, все «приложение» работает

Без реактивности более-менее сложное приложение может начать глючить вплоть до невозможности использования.

0
lega ,  
Классный стектрейс, сразу понятно, где ошибка :-)
У этой ошибки нет трейса, т.к. это «выражение» находится в DOM, грубо говоря там 1 строка трейса, что и выводится, так же проблемный элемент подсвечивается, так что найти проблему очень просто.

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

Можно даже заморочится и делать разные компоненты на разных версиях фреймворка (кстати — идея, для плавного апргрейда).
0
vintage ,   * (был изменён)
У этой ошибки нет трейса, т.к. это «выражение» находится в DOM, грубо говоря там 1 строка трейса, что и выводится, так же проблемный элемент подсвечивается, так что найти проблему очень просто.

Исключение возникает не в выражении, а в коде, который из него вызывается.


Как раз наоборот, сложное приложение состоит из изолированных компонентов которые никак не влияют друг на друга побочными эффектами.

Ещё как влияют. Пользователь изменил своё имя — оно должно поменяться везде.

0
lega ,  
Исключение возникает не в выражении, а в коде, который из него вызывается.
Все, понял. Для этого кейса трейс до throw не проброшен, надо будет добавить, хотя это мелочи.

Пользователь изменил своё имя — оно должно поменяться везде.
Ключевое слово «побочными эффектами», если один компонент поменял имя, он отразил изменения в сервисе, другие компоненты получили это изменение из сервиса (как вариант архитектуры). Если в каком либо компоненте что-то сломалось, оно никак не повиляет* на другие компоненты.
0
lega ,  
Хотел поправить, а там все в порядке, проблема в примере, throw строки трейса не дает, при настящей ошибке трейс есть, пример.
0
vintage ,  

Блин, точно, извиняюсь.

0
lega ,  
Да и я не позиционирую это как какую-то супер фичу, просто вызываю одну и ту же функцию при возниконовении исключений, ничего сверхестественного.
Странно, что подобной мелочи нет во многих вреймворках.
0
vintage ,  

Ну, стектрейс-то хотябы не надо проглатывать.

+1
TimTowdy ,  
Большая часть перечисленных вами вещей уж слишком opinionated, и просто по определению должна быть не в core фреймворка, а в стороннем модуле. Тот, кто потащит все это в core имеет очень низкие шансы попасть в мейнстрим.

И тут все верно, по количеству сторонних модулей, Vue, из-за своей молодости проигрывает. Но если руководствоваться только этим показателем, то нужно всегда выбирать jQuery.
0
franzose ,  

Ну, лично я за компонентность, а не монолиты)

0
vintage ,  
  • микромодульность vue не умеет тоже :-) В микромодульном фреймворке core нет по определению, ибо каждый модуль — сам себе маленький core.
+1
TimTowdy ,  
Предлагаю фанатам React провести мысленный эксперимент: представьте, что в 2013 году Facebook выпускает не React, а Vue (версии 2). А сам React (в текущем виде) выходит в 2016. Как вы думаете, смог бы React набрать хоть какой-то значимый вес? Простили бы ему в 2016 году JSX?
+2
taujavarob ,  
Предлагаю фанатам React провести мысленный эксперимент: представьте, что в 2013 году Facebook выпускает не React, а Vue (версии 2)
Это невозможно - Facebook никогда не выпустил бы такое как Vue! ;-)
+2
VladVR ,  
Абсолютно ничего бы не изменилось. Vue — всего лишь «еще один фреймворк», по крайней мере если судить по тому как его презентовал автор. React предлагает принципиальное отличие. Там где «все остальные фреймворки» тащат javascript в разметку, react затащил разметку в javascript. Совместно с typescript, это еще и дает то, что весь рендер типизован.
А это в свою очередь дает то, что если человек опечатался где то, то он получит исчерпывающее сообщение об ошибке на этапе сборки приложения. А не типичную ситуацию «обычного порошка», когда ты собрал приложение, запустил, и получил пустое место, там где должен быть какой то текст. Или не вставилась директива/компонент. И сиди догадывайся что не так. Ибо возможностей для отладки около нуля, нормальных сообщений об ошибках примерно столько же, валится по совершенно непонятным причинам.
И опять даже если использовать реакт без типизации, и допущена ошибка, во первых с наибольшей вероятностью будет стектрейс с указанием компоненты, строчки и позиции, где эта ошибка случилась, во вторых, если оно не упало, а просто «не работает», то можно поставить брейкпоинт и посмотреть содержимое всех переменных, а не догадываться, чему они могли бы быть равны в тот момент когда ошибка случилась, а не тогда, когда открыл батаранг, но уже поздно.

Еще один концептуальный шаг вперед, это redux и PureComponent вместо обычного Component. Также как и в случае с Flux, cостояние полностью отрывается от представления, и вся концепция приложения разрывается на 3 части, но в отличие от Flux, две части из трех становятся чистыми (pure).
1) новое состояние = чистая функция от двух параметров — предыдущего состояния и «возбудителя»
2) разметка = чистая функция от состояния
3) сервисы, в них смещен весь «нечистый» код, в частности асинхронный.
Конечно команду надо сильно попинывать, чтобы не нарушали концепцию, но возможность иметь две трети приложения написанными чистым кодом того стоят.
Второй ангуляр кстати очень неплохо ударил по этому фронту, даже свою реализацию redux написали, хоть и не по феншую совершенно. Однако если на нее не смотреть, а взять обычный, православный redux, и stateless компоненты, то можно достичь близкого результата. Терпимого я бы сказал, в условиях того, что заказчик уперся и хочет второй ангуляр хоть ты тресни.
0
raveclassic ,  
заказчик уперся и хочет второй ангуляр хоть ты тресни

до слез

0
babylon ,  
Там где «все остальные фреймворки» тащат javascript в разметку, react затащил разметку в javascript. Совместно с typescript, это еще и дает то, что весь рендер типизован.

Согласен с комментом. Есть ещё jsonnet

0
staticlab ,  
представьте, что в 2013 году Facebook выпускает не React, а Vue (версии 2)

просто говорили бы, что ФБ тупо скопировал всё у Гугла.

0
Fen1kz ,   * (был изменён)

deleted

+1
cdrw3 ,  
Эх, помнится на заре моей юности такие холивары устраивали по вопросу, на чем лучше писать — на delphi или с++))
Только не бейте меня сильно (react в своих проектах не использую), но нас раньше учили отделять код от верстки, а сейчас JSX позиционируется чуть ли не как панацея от всех бед. Что изменилось?
+1
indestructable ,  

Нужно отделять бизнес-логику от верстки, код управления состоянием от верстки, служебный код (логгирование, замеры производительности) от верстки.


Но код, управляющий версткой, от верстки отделять не нужно.

0
vintage ,  

Нужно отделять всё, что отделяется. В частности программный код и декларативную композицию.

0
raveclassic ,  

Что мешает в декларативной композиции использовать возможности языка вместо кастомных DSL?

0
vintage ,  

Теряется собственно декларативность.

0
raveclassic ,   * (был изменён)

Теряется, если ее намеренно терять. Вам точно так же в code-behind классах для XAML компонентов (типичный представитель view) никто не запретит ходить в базу. Так какой смысл в этом параноидальном отделении кода для view от шаблона для view?
А если не плодить сайд-эффектов, то декларативность остается.

0
vintage ,  

Как вы думаете, почему конфиги пишут на ini/yaml/xml/json, а не на js/php/c#/java?

0
raveclassic ,  

Не знаю, я обычно на js пишу :) Тот же вебпак вспомнить…
Не представляю, какая жесть писать конфиг к нему в виде json. К нему и так писать конфиг жесть, но json…
Только если с кастомной шаблонизацией внутри — привет DSL.

0
vintage ,  

Попробуйте MAM — там вообще никаких конфигов не надо писать.

0
raveclassic ,  

MAM?

0
vintage ,  

MAM

0
VladVR ,  
Вероятно потому что конфиг это сериализуемые данные. Какой правильный ответ то?
К слову мне в мире C# всегда было непонятно, почему build-процедуры пишутся на каком то левом языке msbuild (поверх xml).
В мире JS, как оказалось его легко писать на том же языке, что и основной проект. Берешь Gulp и вперед.
И, внезапно, в последнее время начали появляться build системы, где можно писать на C#, слышал на дотнексте про fake и cake (т.н. f-sharp make и c-sharp make).
Тоже можно было задавать пространные риторические вопросы, типа «а угадай почему билд скрипты пишут на xml» намекая на то, что существует в природе какая то логическая связь и собеседник должен о ней догадаться и склониться к твоей точке зрения. Однако, внезапно оказалось, что причина то банальна, «вчера» сделали как смогли, а «сегодня» делают, как правильно/удобно, а логическая связь — неверна.
0
vintage ,  

Правильный ответ: возможность различного анализа без исполнения. Простой пример: из view.tree благодаря декларативности очень легко достать информацию о классах, свойствах, типах, связях компонент. Сейчас я пилю абстрактный редактор, который может взять любой компонент и как угодно его изменить. А сделать такое с JSX, например, не получится.


0
VladVR ,  
А сделать такое с JSX, например, не получится.

«Такое» можно сделать даже в компилируемой среде .Net. А в мире скриптов такое заявлять совсем кощунственно. Именно так работают фиддлеры. Человек в браузере пишет jsx или, к примеру, typescript, нажимает кнопку, написанный код уезжает на сервер, там транспайлер его жует, и результат выдается обратно в браузер. Останется прикрутить поверх jsx свой редактор, и «такое» будет отлично работать.
0
babylon ,  

Многое из того что потом кодируется напрямую зависит от формата данных.
Давайте лучше обсудим apache avro vs MsgPack
Быстрее это всё в текстовом редакторе набрать в JSON схемах.

0
vintage ,  
Останется прикрутить поверх jsx свой редактор, и «такое» будет отлично работать.

Вы не забыли, что JSX — это не XML, а JS, с "мощностью" которого не каждая IDE-то толком может совладать?

0
VladVR ,  
Взамен на типизацию, возможности отладки, вменяемые сообщения об ошибках.
Ну и широкоизвестный язык, который лет 20 живет вместо узкоспециализированного DSL, который умрет через пару лет.
0
VolCh ,  
Нужно отделять всё, что отделяется.

Утверждения с универсальными квантификаторами редко бывают истинны, если касаются практических задач. В данном случае, отделять нужно то, что повышает читаемость, поддерживаемость и прочие "хорошие" метрики кода, но не более, а не всё, что можно отделеить в теории.

+1
VolCh ,  

В нормальном JSX кода не больше чем в вёрстке шаблона на любом, ну, почти любом, шаблонизаторе. А императивного кода и того меньше из-за невозможности использовать if/else, for и т. п. внутри разметки.