Сегодня я был изумлен тем, как обычно позитивное и дружелюбное сообщество Vue.js скатилось в печальное противостояние. Две недели назад создатель Vue Эван Ю опубликовал предложение (RFC) с новым функциональным API для компонентов в грядущем Vue 3.0. Сегодня критическое обсуждение на Reddit и аналогичные комментарии на Hacker News вызвали наплыв разработчиков в изначальный RFC с возмущениями, порой даже чересчур резкими.


Там заявлялось примерно следующее:


  • Весь код на Vue придется переписать совершенно по-новому, потому что существующий синтаксис будет убран
  • Все то время, что люди потратили на изучение Vue, оказалось зря, потому что все поменяется
  • Новый синтаксис оказался хуже старого, не дает внятной структуры и порождает спагетти-код
  • Команда Vue выкатила большое изменение, ни с кем не посоветовавшись
  • Vue превращается в React!
  • Или нет, в AngularJS/Angular!
  • Весь HTML теперь придется писать в одну огромную строку!

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


Я был человеком, который написал этот первый комментарий. Так вышло, что я получил нотификацию о новом RFC, сразу же прочел его и обнаружил, что это как раз то, чего я бы хотел от Vue 3.0 и написал об этом комментарий в течение 15 минут после публикации RFC, чтобы выразить свою благодарность. В этом посте я надеюсь раскрыть эту тему, почему я считаю новое API такой хорошей идеей. Но сперва, позвольте ответить на заявления критиков.


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


  • Вам не понадобится ничего переписывать с нуля, если вы этого не хотите – новый синтаксис является дополнением, в то время как старый останется с нами на протяжении Vue 3.0 до тех пор, пока его активно используют. Даже если он в итоге будет убран из основного кода, его можно будет легко вернуть обратно с помощью плагинов.
  • Время на обучение Vue не потрачено зря – в новом синтаксисе работают так же, как и раньше, уже знакомые вам концепции, такие как однофайловые компоненты, шаблоны и локальные стили.
  • Изменение не было сделано без обсуждения – этот RFC и есть обсуждение. Новому синтаксису еще далеко до окончательного релиза.
  • И нет, HTML не обязательно нужно писать как огромную строку

Был еще несколько субъективный пункт о том, что новый синтаксис порождает менее структурированный код. Я хочу продемонстрировать это на простом примере, который объяснит почему я настолько в восторге от RFC и почему я думаю, что новый подход приведет к более структурированному коду


Представьте такой компонент, который дает пользователю ввести информацию о своем питомце и обновляется по мере ввода данных. При этом:


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


Внешний вид компонента


Вы можете увидеть живое демо с компонентом здесь и также посмотреть исходный код для Vue 2.x вот здесь (файл components/Vue2.vue).


Рассмотрим Javascript-часть этого компонента:


  data() {
    return {
      petName: "",
      petColor: "#000",
      petSize: ""
    };
  },
  computed: {
    header: function() {
      if (this.petName) {
        return "My Pet " + this.petName;
      }
      return "Enter Pet Details";
    },
    petColorDarker: function() {
      return tinycolor(this.petColor)
        .darken()
        .toString();
    },
    shadow: function() {
      return "2px 2px " + this.petColorDarker;
    },
    borderStyle: function() {
      switch (this.petSize) {
        case "Small":
          return "dotted";
        case "Medium":
          return "dashed";
        default:
          return "solid";
      }
    },
    headerSize: function() {
      switch (this.petSize) {
        case "Small":
          return "12px";
        case "Large":
          return "60px";
        default:
          return "30px";
      }
    }
  }

В принципе, у нас есть какие-то данные и различные свойства, вычисляемые из этих данных. Заметьте, что во Vue 2.x нет способа положить связанные вещи вместе. Мы не можем разместить объявление petColor рядом с вычисляемым petColorDarker, потому что во Vue 2.x они группируются по типам.


Конечно, для такого маленького примера это не сильно важно. Но представьте пример побольше, в котором есть куски функциональности с необходимыми данными, вычисляемыми свойствами, методами и даже с парой вотчеров. Сейчас нет хорошего способа объединить связанные сущности вместе! Кто-то может подумать о миксинах или компонентов высшего порядка, но у них есть проблемы – сложно увидеть откуда берутся эти свойства, а также есть проблемы конфликта имен.


Новый синтаксис предлагает огранизацию компонентов по связанной функциональности, вместо типа значения. Это похоже на то как вы организуете файлы на своем компьютере – обычно вы не делаете отдельные папки "excel-таблицы" и "word-документы", скорее будут папки "работа" или "планирование отпуска". Давайте представим, как будет выглядеть наш компонент в предложенном новом синтаксисе (насколько это получится без возможности запустить код – дайте знать, если найдете какие-то баги):


  setup() {
    // Pet name
    const petName = value("");
    const header = computed(() => {
      if (petName.value) {
        return "My Pet " + petName.value;
      }
      return "Enter Pet Details";
    });

    // Pet color
    const petColor = value("#000");
    const petColorDarker = computed(() => {
      return tinycolor(petColor.value)
        .darken()
        .toString();
    });
    const shadow = computed(() => "2px 2px " + petColorDarker.value);

    // Pet size
    const petSize = value("");
    const borderStyle = computed(() => {
      switch (petSize.value) {
        case "Small":
          return "dotted";
        case "Medium":
          return "dashed";
        default:
          return "solid";
      }
    });
    const headerSize = computed(() => {
      switch (petSize.value) {
        case "Small":
          return "12px";
        case "Large":
          return "60px";
        default:
          return "30px";
      }
    });

    // All properties we can bind to in our template
    return {
      petName,
      header,
      petColor,
      shadow,
      petSize,
      borderStyle,
      headerSize
    };
  }

Заметим, что:


  • Удивительно просто сгруппировать связанные сущности вместе
  • Глядя на возвращаемое значение функции setup мы сразу видим, к чему у нас есть доступ в шаблоне.

Кроме того, новый синтаксис предоставляет полную поддержку Typescript, что было трудно достижимо в объектном синтаксисе Vue 2.x. А еще мы можем зарефакторить нашу логику, перенеся в переиспользуемые функции. Что-то вроде такого:


function usePetName() {
  const petName = value("");
  const header = computed(() => {
    if (petName.value) {
      return "My Pet " + petName.value;
    }
    return "Enter Pet Details";
  });
  return {
    petName,
    header
  };
}

function usePetColor() {
  const petColor = value("#000");
  const petColorDarker = computed(() => {
    return tinycolor(petColor.value)
      .darken()
      .toString();
  });
  return {
    petColor,
    petColorDarker
  };
}

function petSizeToBorderStyle(sizeWrapper) {
  const borderStyle = computed(() => {
    switch (sizeWrapper.value) {
      case "Small":
        return "dotted";
      case "Medium":
        return "dashed";
      default:
        return "solid";
    }
  });
  return { borderStyle };
}

function petSizeToHeaderSize(petSizeWrapper) {
  const headerSize = computed(() => {
    switch (petSizeWrapper.value) {
      case "Small":
        return "12px";
      case "Large":
        return "60px";
      default:
        return "30px";
    }
  });
  return { headerSize };
}

export default {
  setup() {
    const { petName, header } = usePetName();
    const { petColor, petColorDarker } = usePetColor();
    const shadow = computed(() => "2px 2px " + petColorDarker.value);
    const petSize = value("");
    const { borderStyle } = petSizeToBorderStyle(petSize);
    const { headerSize } = petSizeToHeaderSize(petSize);
    return {
      petName,
      header,
      petColor,
      shadow,
      petSize,
      borderStyle,
      headerSize
    };
  }
};

Во Vue 2.x я часто обнаруживал, что я пишу "монструозный компонент", который сложно разбить на мелкие кусочки – он не может разделиться на меньшие компоненты, потому что слишком много всего происходит на основе небольшого количества переменных состояния. Однако с новым предложенным синтаксисом видно, что можно легко выделить логику из больших компонентов в отдельные кусочки, вынести в отдельные файлы, если нужно, получив маленькие и легкие для понимания функции и компоненты.


Был ли у Vue более темный день? Скорее всего, нет. Бывшее единым сообщество вокруг проекта раскололось. Но у меня есть надежда, что люди взглянут еще раз на RFC, который ничего не ломает, поскольку позволяет людям все так же группировать сущности по типу, если им это нравится, но также позволяет намного больше – более понятный и чистый код, больше возможностей для библиотек и полная поддержка Typescript.


И наконец, при использовании open source, неплохо бы помнить, что его разработчики вкладывают немало усилий в то, что вам достается бесплатно. Чересчур резкая критика, которую мы видим сегодня, это не то что нам подходит. К счастью, неуважительные комментарии были в меньшинстве (пусть и значительном), а большинство было способно выражаться в более подобающем тоне.

Комментарии (127)


  1. interprise
    23.06.2019 16:30

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


  1. EvilGenius18
    23.06.2019 16:48
    +1

    Этот API приносит мало пользы, но много путаницы, теперь все новички должны будут понять не только стандартный и компонентный (.vue) синтакс и все различия между ними, но и этот новый группированный синтакс, который к тому же можно будет писать 2-мя различными способами (как указано в примере), что усложнит изучение.

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

    В чем вообще преимущество группировки? На мой взгляд, как раз, разделение на типы (data, methods, computed) более наглядный и структурированный способ разработки.


    1. justboris Автор
      23.06.2019 18:35

      Этот API приносит мало пользы, но много путаницы

      Статья же как раз показывает обратное, с примерами.


      Все примеры теперь могут быть написаны 4-мя различными способами

      Какими способами? В статье есть только два варианта: 2.х и предложенный 3.х. Откуда 4 способа берутся?


      В чем вообще преимущество группировки? На мой взгляд, как раз, разделение на типы (data, methods, computed) более наглядный и структурированный способ разработки.

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


      1. qellex
        23.06.2019 19:33

        *Мой опыт с vue -это 1 день чтения документации и 1 день манкикодинга небольшого компонент для своего петпроекта, в общем я полный ламер во всех этих ваших фронтенд штуках*
        С моей точки зрения стало хуже, в первом примере я долго не въезжал каким образом все драматически лучше организовалось, пока не понял, что единственное что приводит к организации это комментарии // Pet name, //Pet color….
        Второй пример уже проще понять, но количество кода выросло на 30%.
        Опять же, я в теме не разбираюсь, но стоит ли вносить такие изменения, которые помогают с «большими» компонентами в любой, даже самый маленький компонент(а на сколько я понимаю когда-то, в дальнейшем, новый подход станет единственным)?


      1. BerkutEagle
        24.06.2019 07:19

        Хотели разделение по фичам? Получите! Без изменения API! :)

        Код
        const petName = {
          data() {
            return {
              petName: ""
            };
          },
          computed: {
            header() {
              if (this.petName) {
                return "My Pet " + this.petName;
              }
              return "Enter Pet Details";
            }
          }
        };
        
        const petColor = {
          data() {
            return {
              petColor: "#000"
            };
          },
          computed: {
            petColorDarker() {
              return tinycolor(this.petColor)
                .darken()
                .toString();
            },
            shadow() {
              return "2px 2px " + this.petColorDarker;
            }
          }
        };
        
        const petSize = {
          data() {
            return {
              petSize: ""
            };
          },
          computed: {
            borderStyle() {
              switch (this.petSize) {
                case "Small":
                  return "dotted";
                case "Medium":
                  return "dashed";
                default:
                  return "solid";
              }
            },
            headerSize() {
              switch (this.petSize) {
                case "Small":
                  return "12px";
                case "Large":
                  return "60px";
                default:
                  return "30px";
              }
            }
          }
        };
        
        export default {
          components: {
            ColorPicker
          },
          data() {
            return {
              ...petName.data(),
              ...petColor.data(),
              ...petSize.data()
            };
          },
          computed: {
            ...petName.computed,
            ...petColor.computed,
            ...petSize.computed
          }
        };
        


        1. justboris Автор
          24.06.2019 10:50

          Хорошо! А теперь сделаем так, чтобы финальный мердж data/computed за нас делал сам фреймворк, и станет вообще отлично.


          1. BerkutEagle
            24.06.2019 11:18
            +1

            И получатся миксины


            1. justboris Автор
              24.06.2019 19:36

              Ну да, и именно здесь на помощь приходит новое API, которое проблемами конфликта имен, как миксины, не обладает.


      1. defusioner
        24.06.2019 08:09

        Jsx синтаксис, createElement, template, и теперь каждый можно дублировать в функциональном стиле. Для сообщества которое стремится быть простым, это слишком. Главная проблема в том что стак оверфлов забьётся множеством вариантов.


    1. Sovetnikov
      23.06.2019 21:45

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


      1. taujavarob
        25.06.2019 13:27
        -1

        это уже не VUE, а что-то другое просто

        Верно. Это… тенденция.

        Angular 1 -> Angular 2 — уже не Angular, а что-то другое.

        React -> React 16.8 with Hooks — уже не React, а что-то другое.

        Vue -> Vue 3 — уже не Vue, а что-то другое.

        Всё верно. Это уже не те и не то! (От них если что и осталось, то только и только… название в качестве мимикрии. Не более того. Не более)

        P.S.
        Ах, да, мы же можем не переписывать старое! — Ну, да, через год никто не поймёт и никто не захочет вообще копаться в старом синтаксисе вообще от слова… совсем!


  1. Anshi85
    23.06.2019 17:21

    Или нет, в AngularJS/Angular!


    Хоть убейте, но не могу понять а что плохого в AngularJS? Да он устарел, но он по прежнему позволяет быстро и просто сделать небольшое SPA, да и структура у него для новичков понятная, в общем мне кажется зря его так, да устаревший, но есть еще порох в пороховницах.


    1. fzn7
      23.06.2019 22:53
      +1

      Вот я смотрю на всю эту js движуху и понимаю что 10 лет назад я свободно на flex/air писал проекты на порядок сложнее и объемнее. Приходится признать, что всем нужны шашечки, а не ехать


      1. defusioner
        24.06.2019 08:06

        Flex :D слышал, там дебажить надо с бубном


        1. fzn7
          24.06.2019 20:38
          -2

          Да, бубен выглядит как две кнопки одна зелёный треугольник, а вторая паучек. Я уверен вы смогли бы разобраться без проблем. А вот разобраться в награмождении кодогенерации из одного языка в другой, трансформации кода под старые vm, фоновых запущенных серверов и эмуляторов, которые обещают типа хот релод, а по факту падают на каждый чих и требуют 5 минут чистить все возможные кэши. Вы парни любите кактус, не смею мешать вам наслаждаться. И да у меня руки кривые, iq 80 в прыжке, не отрицаю


          1. defusioner
            25.06.2019 00:32
            +1

            Ничего не падает, что вы придумали)


            1. fzn7
              25.06.2019 02:53

              React-native, например, падает. Но я повторюсь, это только у меня, я не претендую, даже цветные носки не ношу


    1. kalininmr
      24.06.2019 01:44

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


  1. vintage
    23.06.2019 18:08

    Поменяли шило на мыло. Могли же сделать нормально:


    Заголовок спойлера
    class MyComponent {
    
        @observable petName = ""
        @computed header() {
            if (this.petName) return "My Pet " + this.petName
            return "Enter Pet Details"
        }
    
        @observable petColor = "#000"
        @computed petColorDarker() {
            return tinycolor(this.petColor).darken().toString()
        }
        @computed shadow() {
            return "2px 2px " + this.petColorDarker
        }
    
        @observable petSize = ""
        @computed borderStyle() {
            switch (this.petSize) {
                case "Small":
                    return "dotted";
                case "Medium":
                    return "dashed";
                default:
                    return "solid";
            }
        }
        @computed headerSize() {
            switch (this.petSize) {
                case "Small":
                    return "12px";
                case "Large":
                    return "60px";
                default:
                    return "30px";
            }
        }
    
    }


    1. justboris Автор
      23.06.2019 18:30

      Вариант с декораторами тоже рассматривался: https://github.com/vuejs/rfcs/blob/function-apis/active-rfcs/0000-function-api.md#type-issues-with-class-api


      В итоге решили на stage-2 proposal не ставить, потому что рискованно.


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


      1. vintage
        23.06.2019 20:45

        В итоге решили на stage-2 proposal не ставить, потому что рискованно.

        А риск-то в чём? Что их выпият из тайпскрипта? Сомнительно.


        1. ElianL
          23.06.2019 21:19

          А при чем тут typescript если речь о JS фреймворке? Поддержка фремворком ts это лишь дополнительная плюшка.

          А на счет того что typescript начнет противоречить стандарту ES — тоже весьма сомнительно. Ведь он изначально позиционировался как надмножество над ES.
          Пока правда не понятно как они будут выкручиваться из данной ситуации с декораторами


          1. Djaler
            23.06.2019 21:27

            задепрекейтят старые, потом выпилят


          1. vintage
            23.06.2019 21:44
            +1

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


            1. defusioner
              24.06.2019 08:12
              -1

              Я считаю что декораторы портят читабельность и плоскость кода. Почему? У меня проект был, чуваки накидывали декораторы везде, что было просто но породило конектов в каждом компоненте так что приложение лагало хуже некуда.


              1. mayorovp
                24.06.2019 09:05

                Так проблема-то была в декораторах или в коннектах? Если что, connect можно и как обычную функцию вызвать...


                1. defusioner
                  24.06.2019 09:10
                  -1

                  Я перешёл от моба к редуксу потому что был невероятный бардак с первым.


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


                  1. mayorovp
                    24.06.2019 09:14

                    А что за бардак был с mobx?


                    1. defusioner
                      24.06.2019 09:18

                      Повсюду был инжекшн целых кусков стора, когда нужно было взять лишь 1-2 флага для компонентов.


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


                      Абсолютно неочевидный devtools, мутабельность.


                      В общем, простота породила беспорядок.


                      1. vintage
                        24.06.2019 09:24
                        +1

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


                        1. defusioner
                          24.06.2019 09:28

                          Да, согласен. Я пришёл на проект и мне пришлось рефакторить все это дело :) там чуваки не знали даже о classnames хелпере


                      1. mayorovp
                        24.06.2019 09:39

                        На самом деле, в mobx можно без труда сделать почти такой же вызов connect как в редаксе, и писать не знающие про стор компоненты:


                        function connect(mapStoreToProps) {
                            return function(WrappedComponent) {
                                return function(props) {
                                    return <Store.Consumer> // ну или inject
                                        {store => <Observer>
                                           {() => <WrappedComponent {...mapStoreToProps(store)} {...props} />}
                                        </Observer>}
                                   </Store.Consumer>
                                }
                            }
                        }

                        Так что инжектить "целые куски стора" в компонент было всего лишь вашим выбором...


                        1. defusioner
                          24.06.2019 09:46

                          То есть та же история что по сабжу, простота на бумаге но чтоб сделать коннект нужен бубен?


                          Потому и перешёл на редакс. Моб был не моим выбором, а, как говорится, poor legacy


                          1. mayorovp
                            24.06.2019 09:52

                            Так connect как раз и является усложнением, без него проще как бы.


                            Но когда "великая проблема библиотеки" решается 11 строками кода — это означает, что и проблема-то была не такая великая.


                            1. defusioner
                              24.06.2019 09:59

                              Я ж говорю о том что есть библиотеки, которые не учат разработчиков чистоте кода. Отсюда и инжекшн повсюду и всего.
                              Также, devtools и mutability.


                              И я считаю что такие либы не стоит использовать. Сорян если задел за живое)


                              1. vintage
                                24.06.2019 10:07

                                devtools и mutability

                                А что с ними не так, кстати?


                                1. mayorovp
                                  24.06.2019 10:13

                                  Ну, у react-devtools известные проблемы с прототипами, акцессорами и обработкой исключений.


                                  Пишем простейший класс...


                                  class Model {
                                      foo = []
                                  
                                      get count() {
                                          return this.foo.length
                                      }
                                  }

                                  … и получаем Uncaught TypeError: Cannot read property 'length' of null в devtools при попытке экземпляр этого класса просмотреть


                                  1. vintage
                                    24.06.2019 10:28

                                    Ну так это проблема react-devtools, а не mobx.


                                  1. defusioner
                                    24.06.2019 11:56

                                    Никогда не писал так как пишите вы, может я что-то не так делаю…


                                    1. mayorovp
                                      24.06.2019 12:18

                                      Это ж MCVE. Разумеется, вот прям именно так же никто никогда не пишет.


                                      1. defusioner
                                        24.06.2019 12:19

                                        Я про классы в джава стайл, мы ведь про реакт говорим


                                        1. mayorovp
                                          24.06.2019 12:36

                                          А где тут "джава стайл"?


                                          1. defusioner
                                            24.06.2019 12:40

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

                                            Мне кажется, вы из ООП или ангуляр бекграунда этот пример сочинили.

                                            Мы ведь не про библиотеку говорим? Причем здесь класс без наследования к компоненту реакта?

                                            Ваш МСВЕ порождает больше вопросов чем смысла)


                                            1. mayorovp
                                              24.06.2019 12:44

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


                                              1. defusioner
                                                24.06.2019 12:51
                                                -1

                                                Я не согласен. Это как если бы вы сказали «хелло ворлд написать можно как угодно, но я пишу в ангуляр стиле и запускаю под реакт девтулз».


                                                1. mayorovp
                                                  24.06.2019 13:19

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


                              1. Odrin
                                24.06.2019 11:46

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


                                1. defusioner
                                  24.06.2019 11:57

                                  Я не соглашусь. Когда водишь хорошую машину (сравним Клио и Ауди а1), многое приходит интуитивно так как Intuitive Design.

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


                                  1. TheShock
                                    24.06.2019 20:11
                                    +1

                                    Потому у редукса комунити в 100 раз больше чем у моба на сегодня

                                    У редукса комунити в 100 раз больше — потому что хуяк-хуяк, накопипастил говнокода, назвал это «Я просто в ФП стиле писал, а не говнокодер» и в продакшн.


                                    1. defusioner
                                      25.06.2019 00:34
                                      -2

                                      Не согласен. Видел примеры не на редаксе которые вот такие хуяк-хуяк. А на редаксе — ducks pattern, лучший. не за что :)


                                      1. TheShock
                                        25.06.2019 02:35
                                        +1

                                        Видел примеры не на редаксе которые вот такие хуяк-хуяк
                                        Конечно. Но только на редаксе говнокод обожествляют.

                                        ducks pattern, лучший
                                        Знаю-знаю. Это тот, который ctrl+c, ctrl+v и наплодили кучу почти одинаковых уток.


                        1. defusioner
                          24.06.2019 09:46

                          По сути хоку написал :)


            1. mayorovp
              24.06.2019 08:47

              Увы, декораторы JS уже несовместимы с декораторами TS (а также с реализованными в babel, причем дважды). Так что популярность "устаревших" декораторов мало что изменит...


              1. vintage
                24.06.2019 09:13
                +1

                А в чём несовместимость?


                1. mayorovp
                  24.06.2019 09:27

                  Ну так почитайте пропозал-то...


                  Старая версия декораторов имела сигнатуру (any, PropertyKey, PropertyDescriptor) -> PropertyDescriptor?.


                  Текущая версия stage2 декораторов: ElementDescriptor -> ElementDescriptor & { extras: Array<ElementDescriptor > }. Как видно, сигнатуры принципиально несовместимые.


                  Разрабатываемая же версия stage2 декораторов, так называемые static decorators, вообще находятся в отдельном пространстве имен и образуют свой небольшой мета-язык.


                  1. vintage
                    24.06.2019 09:31

                    Какой ужас, при обновлении тайпскрипта придётся переписать несколько функций.


                    1. mayorovp
                      24.06.2019 09:42
                      +1

                      Да пусть они уже хоть что-то выпустят! Такое ощущение, что декораторы в мусорке stage0 находятся, а не на stage2...


            1. Clasen01
              24.06.2019 09:06
              +1

              Но типизация — это вещь сугубо опциональная. Зачем она нужна на каком нибудь лендинге, где весь js — это слайдер и мобильное меню?


              1. vintage
                24.06.2019 09:15
                -1

                Затем, чтобы автодополнение работало и ошибки подсвечивались. Перспектива дебажить пол дня паршивый лендиг из-за мелкой опечатки — такое себе.


              1. TheYellingChives
                24.06.2019 10:06

                На лендингах вообще ничего ненадо кроме HTML и CSS. Но я раз за разом натыкаюсь на лендинги в один экран написаные на Angular/React/Vue. Это я объяснить могу исключительно тем что создаются они каким-то интересным генератором и в огромных количествах.


                1. Alexufo
                  24.06.2019 12:41

                  Либо кто то совмещает приятное с бесполезным.


            1. ElianL
              24.06.2019 12:49

              В JS врятли появится типизация. Так как в рантайме она не нужна. Да и зачем тащить лишний код в браузер когда можно все проверить на этапе сборки?


              1. mayorovp
                24.06.2019 13:22

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


                Но появится она там всё равно вряд ли.


                1. Aingis
                  24.06.2019 15:04

                  Не поможет, так как никогда неизвестно какие данные придут извне. Только разве что в виде подсказок для оптимизирующего компилятора. Вроде бы в V8 объявляли такое, но сходу загуглить что-то не удалось.


                  1. mayorovp
                    24.06.2019 15:10

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


          1. mayorovp
            24.06.2019 08:49

            Пока правда не понятно как они будут выкручиваться из данной ситуации с декораторами

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


        1. mrZipp
          24.06.2019 09:06

          Наверное, потому что не хотели чистый JS выпиливать)


  1. avprinciple
    23.06.2019 18:25
    +1

    То чувство, когда собрался учить Vue, радуешься русской документации, смотришь на комментарии этой статьи, и понимаешь, что не знаешь, что делать, как учить :(


    1. Djaler
      23.06.2019 19:07
      +1

      Учить как есть. От небольшой смены синтаксиса базовые концепты не изменятся


    1. justboris Автор
      23.06.2019 20:35

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


    1. defusioner
      24.06.2019 09:02

      Хочешь быть хорошим фронтом — учи реакт. Быстрым — вью. Пока, конечно, 6 вариантов написания компонента не заполонило сеть :)


      1. symbix
        24.06.2019 14:04

        а Angular — это какой фронт? :)


        1. defusioner
          24.06.2019 14:19
          +1

          А вот на этот вопрос каждый должен ответить сам


        1. BOM
          24.06.2019 16:59

          Стабильный, стандартизированный, многофункциональный.


          1. Per_Ardua
            25.06.2019 12:12

            Этакий Иван-аккордионист. Надёжный как скала, пока не выпьет. Простой как доска, пока не выпьет. И медленный, как трактор. Тоже, пока не выпьет.


            1. k12th
              25.06.2019 12:37

              Почему-то вспоминается "пик Баллмера"...


    1. BOM
      24.06.2019 16:56

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


  1. Marwin
    23.06.2019 18:43

    Вот-вот, я тоже недавно решился немного прокачать фронт, узнав получше про Vue, а тут какие-то перетряски. Простите за нубский вопрос, ибо я бекендер, но… посоветуйте, что есть легковесного для управления стейтом и домом без всяких вебпаков. Я пишу на asp.net, и иногда надо добавить динамики в DOM, а jquery и стейт в инпутах — явно не то, о чем я мечтал )) Или всё норм, уляжется, и можно сразу начинать с Vue 3?


    1. justboris Автор
      23.06.2019 19:00

      Vue – обсуждаемое API лишь малая часть фреймворка. Директивы, реактивность, синтаксис шаблонов останутся такими же. От этой перетряски больше шуму чем реально ломающих изменений (о чем и статья).


      Если же не Vue, то я бы предложил lit-element – библиотеку поверх веб-компонентов.


    1. apapacy
      23.06.2019 19:14

      Я сам пытался как можно дольше не пользоваться webpack или другом компоновщика и разрабатывал все на requirejs. В какой то момент все ушло настолько далеко от модели без компоновщика что об этом уже никто не вспоминает. Конечно если у Вас все генерируется на сервере можно и jquery плюс простые скрипты. Авторы статьи как мне кажется немного сгустили краски. Так что не имеет смысла дожидаться пока все утихнет. В конце концов если vue 3 окажется фатально несовместимой с vue 2 что ещё не факт, то будут они сосуществовать параллельно. Есть тому пример что сейчас на первой версии Angular по прежнему разрабатывают приложения и не задумываются о переходе на более новые версии.


    1. symbix
      24.06.2019 06:34
      -1

      Не надо бояться вебпаков, в них нет ничего страшного. Говорю как фуллстек, долго бывший бэкендером :) Да и typescript вам как дотнетчику сразу должен понравиться.


      При такой постановке задачи vue вполне подходит.


    1. norguhtar
      24.06.2019 09:44

      Краткий ответ никак. Используйте webpack и компоненты. Это удобнее.


    1. daruvayc0
      24.06.2019 20:00

      Vue + Vuex хорошее решение для Вас. Можете еще посмотреть в сторону нового и так же легковесного фрейморка Svelte. У них тоже хорошая документация с примерами, единственное не знаю как там с хранилище.


  1. ZXZs
    23.06.2019 20:14

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


  1. NerVik
    23.06.2019 22:00
    +1

    сперва мне тоже не понравился новый синтаксис, но перечитав RFC через пару дней я прям влюбился в него, и жду когда же уже наконец выйдет 3 версия. новый подход это смесь лучшего из объектного стиля и из class components.


    1. NerVik
      23.06.2019 22:01
      +2

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


      1. VokaMut
        24.06.2019 08:41

        Объясните пожалуйста почему миксины это плохо?


        1. defusioner
          24.06.2019 08:46

          Вложенный неотслеживаемый код, логика «внутри» компонента, в отличие от тех же hoc, которые снаружи. Миксины это как в первом ангуляре компоненты, которые определяют логику но чтоб понять откуда ноги растут, нужно прочесать десять файлов.


          1. defusioner
            24.06.2019 08:48

            Плюс возьмём два миксина записанные массивом в компоненте. Каждый имеет цикл жизни. Как их сопоставить с компонентом-реализацией, когда там вложение? А если миксин в миксине? Вот-вот.


          1. VokaMut
            24.06.2019 08:54

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


            1. defusioner
              24.06.2019 09:00

              HOC, который по сути враппер а не флажок в компоненте


            1. NerVik
              24.06.2019 09:27

              HOC, scoped-slots, во вью3 hooks, вынос простых функций в отдельные js файлы


        1. NerVik
          24.06.2019 09:23

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


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


          во вью2 её предлагают решать с помощью договоренностей, что всё, в миксине называется с префиксом $_MixinName_methodName. он решает проблему, но читать становится неприятно.


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


          1. VokaMut
            24.06.2019 10:22

            Спасибо за ответ. Я использую миксины как самодостаточные куски кода, которые выполняются отдельно от кода основного компонента. Как например trait в php.
            Например:
            В админке нужно реализовать возможность блокировать редактирование и создание новостей пока на сайте ведутся технические работы. Я создаю миксин, который раз в 10 секунд get запросом проверяет, не ведутся ли сейчас технические работы, если ведутся то показывается оповещение.
            Миксин никак не взаимодействует с компонентом, а просто дополняет его.


            1. mayorovp
              24.06.2019 10:34

              "Самодостаточность" куска кода никак не поможет в случае конфликта внутренних имен.


              И да, трейты в php имеют те же самые проблемы.


  1. faiwer
    24.06.2019 00:04

    Хехе. Очень напоминает knockoutJS (явное описание value(), computed()) и нового reactJS (useHooks). На самом деле концепция с хуками оказалась довольно удобной. Думаю во Vue она тоже "выстрельнет". Разделение на уровне methods, computed и пр. куда менее логично, чем группировка на основе функциональностей. А тут либо хуки, либо миксины, либо инкапсуляция (2-й вариант от Vintage).


  1. Taraflex
    24.06.2019 00:24
    +1

    Хмм… выглядит как недоделанный svelte3


  1. VladimirAndreev
    24.06.2019 00:36
    +1

    Я вот не понимаю, нравится вам v2, не нравится v3 — ну так напишите в ваших зависимостях 2.* и живите счастливо дальше, в чём проблема то?


    1. Alexufo
      24.06.2019 01:12

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

      Верующие всегда с ждут благодатного огня раз в год в великую субботу [ Эван опубликовал коммит 8 июня — суббота что как бы намекает]. И я вам напомню, что его не приход обозначает конец света. Чего, собственно, все и напряглись.


    1. vlaaadislav
      24.06.2019 02:10

      Более того, если так нравится vue2 — так пиши компоненты как раньше, старый синтаксис никуда не денется.
      Надеюсь из-за этого недовольства vue3 не окажется с миксинами, компонентами по 500 строк и vue class component.


  1. TheYellingChives
    24.06.2019 10:01

    Основная проблема треш и угар начались не из-за RFC, а из-за того что Эван переписывал историю. В первой версии RFC новый новый синтаксис преподносился как Standart build, а поддержка старого Compatibility build. После поднявшегося вайна они изменили это на Lean и Standart соответственно.

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

    Вообщем мне кажеться Эвану и ко. просто очень хочеться в рокет-саенс, при том что их продукт завоевал популярность как раз отсутствием этой самой сложности.


  1. zim32
    24.06.2019 10:41

    Не понимаю. Народ это фронтэнд. Вы еще не смирились с тем что каждую неделю выходит что-то новое юез оглядки нп обратную совместимость? Тогда вам тут не место


    1. ElianL
      24.06.2019 12:58

      вы немного отстали от жизни) давно уже не выходит «по фреймворку в неделю».
      Три основных игрока уже давно закрепились. React/Vue/Angular.
      И обратную совместимоть давно никто не ломал. Да и Vue 3 ее не ломает.
      Хотя мажорная версия имеет на это полное право


      1. zim32
        24.06.2019 13:05

        Кпкой там версии у нас последний ангулар?


        1. vlreshet
          24.06.2019 15:45

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


          1. ixolit
            24.06.2019 17:30

            Начиная со втрого это все один и тот же фреймворк, легко апгрейдящийся на следующую версию


          1. symbix
            24.06.2019 18:30

            Не припоминаю, чтобы прям-прям совсем ломали после 4-ки. Депрекейтили — это да, но там достаточно было времени (тем более если использовать всякие штуки типа HttpClient не напрямую, а через свой слой абстракции). Для Rx есть compat-прослойка, опять же.


  1. ksenofobius
    24.06.2019 11:29

    Лично мне нововведения зашли. Это неплохо позволит сделать код чище, разбить компоненты на составляющие, эдакое движение в сторону single responseability, но от части я и негодование могу понять, порог вхождения это немного увеличит (но вряд ли это будет критично)


  1. k12th
    24.06.2019 12:04

    Лучше бы уже сделали что-то с vuex, чтобы оно было не stringly typed. Бизнес-логика-то именно там находится, а не в компонентах.


    1. ksenofobius
      24.06.2019 13:59

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


      1. k12th
        24.06.2019 14:09

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


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


        1. ksenofobius
          24.06.2019 14:17

          Перемешивать необязательно, можно использовать DI. А если у вас бизнес логика хранится непосредственно в сторе как вы ее в таком случае мокаете? Выходит что у стореджа в таком случае 2 ответственности, это непосредственно хранить и обрабатывать данные, и еще бизнес логика (которую тоже неплохо было бы покрыть тестами)


          1. k12th
            24.06.2019 14:31

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


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

            А в чем проблема ее замокать? Содержимое стора это просто POJO. Если вы про тестирование компонентов, так я тестирую именно сам компонент, полагаясь на то что стор работает как надо (т.к. покрыт отдельными тестами).
            Иногда, если что-то большое/нетривиальное, я выношу код в отдельные чистые функции, которые потом просто вызываются из мутаций и т.д. Полагаю, до некоторой степени это можно назвать разделением стора и бизнес-логики.


            и еще бизнес логика (которую тоже неплохо было бы покрыть тестами)

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


            1. ksenofobius
              24.06.2019 15:04

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

              Пожалуй я об этом и писал, вообще для DI в чистом виде фреймворк использовать необязательно, можно инжектить перед инициализацией вьюкса, тут как по мне проблем нет (да и в самом вью неплохой ioc).
              Ну вот у вас получается, что одна ответственность размазалась по стору и по некой отдельной бизнес-логике:)

              А вот почему размазалась я не догоняю, разная же ответственность) бизнес логика не должна быть привязана к vuex. Во вью хорошо что кроме вьюкс по сути и нет ничего для стейта, но если рассматривать другие фреймворки, где для хранения стейта можно использовать не 1 механизм, то как тогда рефакторить код в случае смены стейта? перепиливать весь функционал? Это по меньшей мере предполагает что код открыт для изменения (а не для расширения). p.s. не холивара ради.


              1. k12th
                24.06.2019 15:20

                разная же ответственность

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


                но если рассматривать другие фреймворки, где для хранения стейта можно использовать не 1 механизм

                Ну это уже какой-то уж очень теоретический случай:) Честно скажу, реакт я уже здорово подзабыл, с хуками и контекстом даже не пробовал (вот там пожалуй да, стоило бы выносить бизнес-логику отдельно), а в ангуляре стейт и так хранится и управляется в отдельных сервисах. Или вы и в ангуляре пишете отдельный сервис для хранения данных и отдельный для работы с ними?


                как тогда рефакторить код в случае смены стейта?

                Да как обычно, нет?:) Мне моя IDE позволяет рефачить что угодно без особой головной боли.


                В общем, вы меня пока не убедили, хотя, безусловно, дискуссия интересная и приятная:)


                1. ksenofobius
                  24.06.2019 15:42

                  В общем, вы меня пока не убедили, хотя, безусловно, дискуссия интересная и приятная:)

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


                  1. k12th
                    24.06.2019 16:16

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


            1. transcengopher
              24.06.2019 17:39

              это просто POJO

              Что забавно — термин означает Plain Old Java Object, и используется программистами на других языках именно в такой форме, хотя Java иногда и не пахнет.
              Наверное от того, что никому не хочется всерьёз дропнуть оттуда "J".


              1. k12th
                24.06.2019 18:00

                Plain Old JavaScript Object в данном случае:)


                Еще встречал вариант POCO (С++/С# Object).


                1. symbix
                  24.06.2019 18:31
                  +1

                  В случае с PHP звучит не очень хорошо.


                  1. k12th
                    24.06.2019 18:35

                    Не повезло-с:)


                  1. dubr
                    24.06.2019 23:42

                    Там еще и A(rrays) вместо O на конце должно быть :)


              1. apapacy
                24.06.2019 23:02

                У этого термина целый спектр значений. Некоторые из них весьма двусмысленны. Наверное именно поэтому термин так полюбился разработчикам slangdefine.org/p/pojo-809e.html


                1. k12th
                  24.06.2019 23:25

                  Я бы не очень полагался на urbandictionary (откуда slangdefine явно парсит контент).


  1. rboots
    24.06.2019 17:21
    +1

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


  1. JSmitty
    24.06.2019 17:37

    просто оставлю это здесь:

    const sharedComputeds = {
        petColorDarker: function() {
          return tinycolor(this.petColor)
            .darken()
            .toString();
        },
        shadow: function() {
          return "2px 2px " + this.petColorDarker;
        },
    }
    
    export default sharedComputeds;
    
    // -------
    
    import { petColorDarker, shadow } from './sharedComputeds';
    
    const MyVueComponent = {
        data() { /* ... */ },
        computed: {
            petColorDarker,
            shadow,
        }
    }
    


    1. Djaler
      24.06.2019 17:47

      А теперь сделайте то же самое с typescript