Темный день для Vue.js

Original author: Daniel Elkington
  • Translation

Сегодня я был изумлен тем, как обычно позитивное и дружелюбное сообщество 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, неплохо бы помнить, что его разработчики вкладывают немало усилий в то, что вам достается бесплатно. Чересчур резкая критика, которую мы видим сегодня, это не то что нам подходит. К счастью, неуважительные комментарии были в меньшинстве (пусть и значительном), а большинство было способно выражаться в более подобающем тоне.

Share post
AdBlock has stolen the banner, but banners are not teeth — they will be back

More
Ads

Comments 135

    0
    Посмотрел пример, прям причин для негодования пока не вижу. Смотрим дальше. Тем более если старый синтаксис будет поддерживаться.
    Добавлю. Особого преимущества от нового синтаксиса также не увидел. Да, появилась формальная возможность группировать данные, у меня такой острой необходимости не возникало, поэтому возможно я и не до конца понял суть нововведений.
      0
      Поддержка typescript дорогого стоит, у меня есть приложение на электроне и теперь с таким синтаксисом я могу легко внедрить typescript и не отстрелить себе ногу
      +11
      Этот API приносит мало пользы, но много путаницы, теперь все новички должны будут понять не только стандартный и компонентный (.vue) синтакс и все различия между ними, но и этот новый группированный синтакс, который к тому же можно будет писать 2-мя различными способами (как указано в примере), что усложнит изучение.

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

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

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


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

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


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

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

          0
          *Мой опыт с vue -это 1 день чтения документации и 1 день манкикодинга небольшого компонент для своего петпроекта, в общем я полный ламер во всех этих ваших фронтенд штуках*
          С моей точки зрения стало хуже, в первом примере я долго не въезжал каким образом все драматически лучше организовалось, пока не понял, что единственное что приводит к организации это комментарии // Pet name, //Pet color….
          Второй пример уже проще понять, но количество кода выросло на 30%.
          Опять же, я в теме не разбираюсь, но стоит ли вносить такие изменения, которые помогают с «большими» компонентами в любой, даже самый маленький компонент(а на сколько я понимаю когда-то, в дальнейшем, новый подход станет единственным)?
            +7
            Хотели разделение по фичам? Получите! Без изменения 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
              }
            };
            

              0

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

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

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

              +1

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

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

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

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

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

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

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

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


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

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

                  –2

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

                    –2

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

                      +1

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

                        +1

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

                        0
                        Adobe слишком долго тупил с ним. Тут все просто, кто протупил — тот выбывает.
                    +1
                    многословен, например.
                    структура кода тоже не ахти получается
                    +1

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


                    Заголовок спойлера
                    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";
                            }
                        }
                    
                    }

                    Ну и то же самое с разделением:


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

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


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


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

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

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

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

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

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

                                –1

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

                                  +3

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


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

                                    –2

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


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

                                      0

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

                                        –2

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


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


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


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

                                          +4

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

                                            0

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

                                            0

                                            На самом деле, в 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

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


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

                                                +1

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


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

                                                  0

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


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

                                                    0
                                                    devtools и mutability

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

                                                      0

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


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


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

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

                                                        0

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

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

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

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

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

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

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

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

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

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

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

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

                                                            0

                                                            const test = new model; console.log(test.count);
                                                            Дело в том что свойство и геттер не статистика.

                                                              0

                                                              Это вы к чему?

                                                          +1
                                                          Я ж говорю о том что есть библиотеки, которые не учат разработчиков чистоте кода.
                                                          Библиотеки ничему учить разработчиков и не должны. Это разработчик должен учиться пользоваться инструментом, которым он работает.
                                                            –5
                                                            Я не соглашусь. Когда водишь хорошую машину (сравним Клио и Ауди а1), многое приходит интуитивно так как Intuitive Design.

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

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

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

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

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

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

                                            0

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

                                              +1

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

                                                0

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


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


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


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

                                                  –1

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

                                                    +2

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

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

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

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

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

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

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


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

                                                      0

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

                                                        +3

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

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

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

                                                  0
                                                  Наверное, потому что не хотели чистый JS выпиливать)
                                              +6
                                              То чувство, когда собрался учить Vue, радуешься русской документации, смотришь на комментарии этой статьи, и понимаешь, что не знаешь, что делать, как учить :(
                                                0
                                                Учить как есть. От небольшой смены синтаксиса базовые концепты не изменятся
                                                  0

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

                                                    0

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

                                                      0

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

                                                        +1
                                                        А вот на этот вопрос каждый должен ответить сам
                                                          0
                                                          Стабильный, стандартизированный, многофункциональный.
                                                            0

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

                                                              0

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

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

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

                                                          0

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


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

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

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


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

                                                                0
                                                                Краткий ответ никак. Используйте webpack и компоненты. Это удобнее.
                                                                  0
                                                                  Vue + Vuex хорошее решение для Вас. Можете еще посмотреть в сторону нового и так же легковесного фрейморка Svelte. У них тоже хорошая документация с примерами, единственное не знаю как там с хранилище.
                                                                  0
                                                                  Новый синтаксис вносит много путаницы. Только комментарии могут помочь разобраться в коде. Лично я никогда не сталкивался с проблемой группировки данных, поэтому топлю за старый или новый, если в будущем его видоизменят.
                                                                    +1

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

                                                                      +3

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

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

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

                                                                            0

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

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

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

                                                                                  0

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

                                                                                +2

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


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


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


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

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

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


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

                                                                            +2

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

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

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

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

                                                                                  Верующие всегда с ждут благодатного огня раз в год в великую субботу [ Эван опубликовал коммит 8 июня — суббота что как бы намекает]. И я вам напомню, что его не приход обозначает конец света. Чего, собственно, все и напряглись.
                                                                                    +1
                                                                                    Более того, если так нравится vue2 — так пиши компоненты как раньше, старый синтаксис никуда не денется.
                                                                                    Надеюсь из-за этого недовольства vue3 не окажется с миксинами, компонентами по 500 строк и vue class component.
                                                                                    +6
                                                                                    Основная проблема треш и угар начались не из-за RFC, а из-за того что Эван переписывал историю. В первой версии RFC новый новый синтаксис преподносился как Standart build, а поддержка старого Compatibility build. После поднявшегося вайна они изменили это на Lean и Standart соответственно.

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

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

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

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

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

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

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

                                                                                              0

                                                                                              Тут вот уже дважды упомянули некий Svelte, который "ещё более лучше". Добавил коммент в закладки :)

                                                                                                –1
                                                                                                Svelte интересен концепциями, но не более. Можете посмотреть доклад Ильи Климова на эту тему, достаточно содержательно и отвечает на вопрос, почему у Svelte мало шансов занять большую нишу
                                                                                                  +3

                                                                                                  Посмотреть где?

                                                                                            0

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

                                                                                              0

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

                                                                                                +1

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

                                                                                                  0

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


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

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

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


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

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


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

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

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

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

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

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


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

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


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

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


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

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

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

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

                                                                                                          0
                                                                                                          это просто POJO

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

                                                                                                            0

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


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

                                                                                                              +2

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

                                                                                                                0

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

                                                                                                                  0
                                                                                                                  Там еще и A(rrays) вместо O на конце должно быть :)
                                                                                                                0
                                                                                                                У этого термина целый спектр значений. Некоторые из них весьма двусмысленны. Наверное именно поэтому термин так полюбился разработчикам slangdefine.org/p/pojo-809e.html
                                                                                                                  0

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

                                                                                                      +3
                                                                                                      Vue достаточно хорош, я бы предпочёл, чтобы его не меняли вообще или меняли очень осмотрительно, так как случайные изменения могут легко превратить лучший в мире фреймворк просто в средний.
                                                                                                        0
                                                                                                        просто оставлю это здесь:
                                                                                                        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,
                                                                                                            }
                                                                                                        }
                                                                                                        

                                                                                                          0
                                                                                                          А теперь сделайте то же самое с typescript
                                                                                                          0
                                                                                                          Иногда от количества вариаций синтаксиса рябит в глазах, и начинаешь с надеждой посматривать в сторону angular/typescript.
                                                                                                          Это, как говорится, слишком много хорошо уже не очень хорошо.

                                                                                                          Only users with full accounts can post comments. Log in, please.