Когда фронтенд-разработчику стоит перейти с React на Vue, а когда это усложнит разработку

Original author: Anthony Gore
  • Translation


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

Переведено при поддержке облачной платформы Mail.ru Cloud Solutions.

Итак, вы разработчик React и решили попробовать Vue. Давайте начнем!

React и Vue — это как Coca-Cola и Pepsi. Многое, что вы можете сделать с помощью React, можно сделать и с помощью Vue. В то же время есть несколько различий, некоторые из которых отражают влияние на Vue фреймфорка Angular.

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

Как сильно различаются React и Vue?


У React и Vue больше сходств, чем различий:

  • это две библиотеки для создания UI;
  • обе быстрые и легкие;
  • имеют компонент-ориентированную архитектуру;
  • используют подход Virtual DOM;
  • обе могут подключаться прямо в HTML-файле или в качестве модуля в более сложной системе сборки на Webpack;
  • обе имеют отдельные, но широко используемые сторонние библиотеки для роутинга и управления состоянием.

Заметные отличия состоят в том, что Vue обычно использует шаблонные HTML-файлы, а React только JavaScript-файлы. В библиотеке Vue также есть изменяемое (mutable) состояние и автоматическая система перерисовки шаблона под названием «реактивность» (reactivity).

Компоненты


В библиотеке Vue компоненты подключаются с помощью API-метода .component, который принимает аргументы id и объекта с переменными определения. Разработчик React, вероятно, заметит знакомые и незнакомые аспекты определения Vue-компонентов в этом коде:

Vue.component('my-component', {
  //<strong> Свойства</strong> Props
  props: [ 'myprop' ],
  // <strong>Внутреннее состояние</strong> Local state
  data() {
    return {
      firstName: 'John',
      lastName: 'Smith'
    }
  },
  // <strong>Вычисляемые значения </strong>Computed property
  computed: {
    fullName() {
      return this.firstName + ' ' + this.lastName;
    }
  },
  // <strong>Шаблон </strong>Template
  template: `
    <div>
      <p>Vue components typically have string templates.
      <p>Here's some local state: {{ firstName }}
      <p>Here's a computed value: {{ fullName }}
      <p>Here's a prop passed down from the parent: {{ myprop }}
    </div>
  `,

  // <strong>Хук жизненного цикла компонента </strong>Lifecycle hook
  created() {
    setTimeout(() => {
      this.message = 'Goodbye World' 
    }, 2000);
  }
});

Шаблон


Как видно, в компоненте есть свойство template, которое представляет из себя строку с HTML-разметкой. Библиотека Vue включает компилятор, который превращает эту строку в рендер-функцию во время исполнения кода. Эти функции рендеринга использует механизм Virtual DOM.

Вы можете не использовать свойство template, если вместо этого решите создать собственную функцию рендеринга. Вы даже можете использовать JSX-разметку из мира React. Но это было бы странно перейти на Vue и делать так — это как приехать в Италию и отказаться от пиццы…

Хуки жизненного цикла


У компонентов Vue методы жизненного цикла похожи на те, что есть у React-компонентов. Например, хук created из примера выше запускается тогда, когда готово состояние (state) компонента, но до того, как компонент прикрепляется к странице. Аналог из мира React — getDerivedStateFromProps.

Но есть одна большая разница: в библиотеке Vue нет аналога реактовского shouldComponentUpdate. В этом нет необходимости ввиду наличия в Vue системы реактивности.

Перерисовка компонента


Одним из шагов инициализации компонента является просмотр всех его свойств и превращение их в геттеры и сеттеры. Как вы видите, свойство message, взятое из первоначальных данных (props) получило два дополнительных метода — get и set:


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

Изменяемое состояние


Для изменения состояния в Vue вам не нужно вызывать отдельный метод this.setState, как это делается в React. Вы просто пишете изменения напрямую:

// React
this.setState({ message: 'Hello World' });
// Vue
this.message = 'Hello World'; 

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

Если переменная message прокидывается дальше как свойство (prop) в дочерние компоненты, то библиотека об этом помнит, и дочерние компоненты также будут автоматически перерисованы. Именно поэтому в библиотеке Vue нет нужды в методе жизненного цикла, аналогичном реактовскому shouldComponentUpdate.

Основной шаблон


В отношении главного файла шаблона проекта Vue скорее похож на Angular. Как и в React, шаблон Vue нужно где-то примонтировать непосредственно на странице:

<body>
  <div id="root"></div>
</body>

// React
ReactDOM.render('...', document.getElementById('root'));

// Vue
new Vue({
  el: '#root'
});

Однако, в отличие от React, вы можете добавлять обычную верстку в этот корневой элемент. Если React при монтировании компонента сотрет всё, что находится внутри элемента #root, то Vue сохранит:

<div id="root">
  <div>You can add more markup to index.html</div>
  <my-component v-bind:myprop="myval"></my-component>
</div>

Также есть способ определения шаблонов дочерних компонентов в корневом html-файле через расширения HTML5, такие как x-template или inline-template. Это не считается лучшей практикой, так как отделяет шаблон от определения всего компонента в целом.

Директивы


Снова, как и в Angular, Vue позволяет расширить возможности компонента с помощью логики «директив». Есть специальные HTML-атрибуты с префиксом v-, например, v-if для рендеринга с условиями или v-bind для привязки выражения к обычному HTML-атрибуту:

new Vue({
  el: '#app',
  data: {
    mybool: true,
    myval: 'Hello World'
  }
});
<div id="app">
  <div v-if="mybool">This renders if mybool is truthy.</div>
  <my-component v-bind:myprop="myval"></my-component>
</div>

Значение, присвоенное директиве, является JS-выражением, поэтому дальше вы сможете ссылаться на свойства данных, в том числе с помощью тернарных операторов и так далее.

Организация проекта


В библиотеке Vue нет официального эквивалента реактовскому react-create-app, однако есть build, сделанный сообществом Vue-разработчиков: create-vue-app.

Официальная рекомендация для запуска проекта на Vue — это vue-cli. Он может генерировать всё — от простого проекта с одним HTML-файлом до полностью упакованного Webpack + Server-Side Rendering-проекта:

$ vue init template-name project-name

Проекты с одним HTML-файлом


Создатель Vue.js Эван Ю (пхининь You Yu Xi) назвал свой проект «прогрессивным фреймворком», потому что он может быть как масштабирован для сложных приложений, так и упрощен для маленьких приложений.

Конечно, React тоже умеет так. Разница в том, что проекты на Vue обычно используют меньше возможностей ES6 и редко используют JSX, таким образом, им не нужно проходить транспиляцию кода с помощью Babel. Плюс вся библиотека Vue умещается в одном файле, нет отдельных файлов для эквивалентов React типа ReactDOM.

Вот как можно добавить Vue в проект с одним HTML-файлом:

<script src="https://unpkg.com/vue/dist/vue.js"></script>

Важно! Если вы не собираетесь использовать шаблонные строки и, следовательно, не нуждаетесь в компиляторе шаблонов, используйте упрощенную версию библиотеки, в которой нет этих функций, — vue.runtime.js. Она меньше полной примерно на 20 КБ.

Компонент в одном файле


Если вам посчастливилось добавить этап сборки вашего проекта с помощью таких инструментов, как Webpack, вы можете использовать Vue's Single File Components (SFCs, Vue-компоненты в одном файле). Это файлы с расширением .vue, они инкапсулируют шаблон компонента, конфигурацию JS и стили в одном файле:

<template>
  <div class="my-class">{{ message }}</div>
</template>
<script>
  export default {
    data() {
      message: 'Hello World'
    }
  }
</script>
<style>
  .my-class { font-weight: bold; }
</style>

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

Существует Webpack-loader под названием vue-loader, который отвечает за сборку SFCs. В процессе сборки шаблон преобразуется в функцию рендеринга, и это идеальный вариант для использования урезанной сборки vue.runtime.js в браузере.

Redux и остальное


Для Vue есть Flux-ориентированная библиотека управления состоянием под названием Vuex. Она и в этот раз похожа на Redux, но есть некоторые отличия.

Что получает разработчик, переходя с React на Vue?


Чтобы полностью разобраться в вопросе, я дополнил статью и рассказал, когда лучше выбрать React, а когда Vue.

Переход на Vue, скорее всего, упростит ввод новых людей в проект. Шаблоны Vue можно писать прямо в HTML. Также для маленьких проектов необязательно знать последние фичи ES++ и настраивать сборку кода через такие инструменты, как Webpack и Babel. Код для Vue можно писать в jQuery-стиле, то есть прямо в шаблон.

Также Vue имеет удобную систему доставки сообщений об изменениях состояния «из коробки». Разработчикам не нужно заморачиваться с вызовом асинхронного метода setState (как в React) или подключать внешние библиотеки для управления доставкой состояния (такие, как Mobx).

Наконец, приложения, написанные с помощью Vue, могут быть заметно легче: зачастую нужна будет только сама библиотека или даже ее урезанная версия vue.runtime.js. В то время как современная разработка на React уже практически невозможна без Babel и громоздких бандлов весом до нескольких мегабайт.

С другой стороны, проекты на Vue могут быть слишком сложны, если у вас большое приложение или сложная логика на клиенте. Если верстка вынесена в HTML-шаблон, становится труднее тестировать части приложения. React, который использует только JS-код, дает более широкие возможности переиспользования и расширения кода. Также, если вы пишете на React, вы без особых затрат сможете переиспользовать ваш код при написании приложений для устройств с помощью React-Native. В случае с Vue так не получится.

Поэтому вывод может быть следующим:

  • если у вас уже долгоживущий проект, и он написан с помощью одной из библиотек, переход на другую должен быть хорошо обоснован. Действительно серьезных различий между ними мало;
  • если же вы запускаете новый проект, то следует ориентироваться на целевые показатели: для более быстрого запуска и более гибкой разработки предпочтительнее Vue, для более сложной бизнес-логики с переиспользованием кода и хорошим покрытием тестами лучше использовать React.

Переведено при поддержке облачной платформы Mail.ru Cloud Solutions.

Mail.ru Group
Building the Internet

Similar posts

Comments 43

    +2
    Для меня ключевым стало то, что Vue достаточно отделён от Javascript и имеет «свой стиль», я как свитчер с рубей и не знающий глубоко js смог сразу писать нормально, на реакте скорее всего у меня получился бы лютый треш. По крайней мере мне так показалось тогда (года 3 назад).
      0
      Vue достаточно отделён от Javascript и имеет «свой стиль»
      У Angular гораздо больше «своего стиля» и есть родная поддержка TypeScript.
        +1
        Angular не рассматривал ибо гугл, а в Vue 3 тоже будет TypeScript.
          0

          а можете рассказать что именно "ибо гугл" означает? вы какой-то ярый противник или что?

            0
            Нет, особой неприязни нет, но по моему мнению у них все сервисы через одно место сделаны.
            0
            А что не так с гуглом?
        +4
        Во Vue.js ниже порог входа. И это, как по мне, киллер-фича. Новые люди, вне зависимости от квалификации, осваивают Vue легко и непринуждённо.

        Естественно, плохо писать можно на любом языке и применяя какой угодно фреймворк. Но касательно данной статьи, накосячить в React гораздо проще.
          +1
          Низкий порог входа с одной стороны это хорошо, а с другой это тонны кривого кода от людей, которые «осваивают легко и непринужденно».
          +1
          выбрал vue потому что в управлении проектом для него можно легко разделить дизайн, вёрстку и JS — получается реактивность добавляется только к тем элементам которые её действительно требуют, а не ко всему блоку
            –7
            Как-то писал на Vue проект крупный. Баг на баге и багом погоняет. Например, приложение могло просто фризиться, потому что в атрибуте тега указывается строковый литерал. А если этот же литерал записать в секции data компонента, и из шаблона сослаться на него как на переменную, то все работает.
            И таких приколов масса.
            Самый лютый: приложение (на Vuex) в какой-то момент вообще просто перестает работать и выдается какая-то ошибка странная (забыл уже конкретно какая). Эта ошибка не гуглится и не исправляется вообще никак. Но если удалить node_modules и переставить заново, то все работает.
              +9
              Вы описали любое крупное приложение на Javascript :)
                0
                Нет. Только в вью у меня такое было. Все остальное хорошо.
                  +1
                  Что остальное хорошо? На чём ещё писали, просто интересно. Вы просто первый встретившийся мне пока человек с такой ситуацией.
                    –2
                    Что остальное хорошо?

                    С другими технологиями баги если и были, то всегда причина была в том где-то я что-то не понимал и делал не так. А тут именно во фреймворке дело.

                    На чём ещё писали, просто интересно.

                    Реакт, нокаут, бэкбон.

                    Вы просто первый встретившийся мне пока человек с такой ситуацией.

                    Из скольки?
                0
                Эта ошибка не гуглится и не исправляется вообще никак. Но если удалить node_modules и переставить заново, то все работает

                Это рецепт решения многих проблем в js/ts мире. Я вот давеча наткнулся на то, что npm устанавливал кое-какой пакет версии 2.14 вместе требуемой 3.15 без каких-либо на то вменяемых причин. И это ломало типизацию. TS просто превратил все связанные через пятое колено типы в any и у меня по всему приложению any расползлось как вирус (несмотря на strict: all). Было очень странно в итоге выяснить, что дело в каком-то баге резолва зависимостей npm.

                  +1
                  Нет. Тут другое. Никаких видимых причин для возникновения ошибки не было. То есть, просто работаешь, работаешь и тут бах — вот эта ошибка. Это точно не конфликт версий, потому что на момент возникновения ошибки никто даже не ставил никаких модулей и не удалял. Обычная работа по программированию.
                  И я не один такой. У всех двух моих коллег эта же ситуация повторялась.
                    0
                    Это точно не конфликт версий

                    Но если удалить node_modules и переставить заново, то все работает.

                    Исходя из чего вы делаете вывод, что это не конфликт версий, если переустановка node_modules что-либо меняет? У вас вариантов то всего остаётся:


                    • конфликт версий (подверсий, подподверсий, ...)
                    • баг компилятора\транспилятора\чегоугодноатора
                    • и то и другое

                    Не очень понимаю причём тут вообще Vue. Во Vue встроен полтергейст?

                      +1
                      Исходя из чего вы делаете вывод, что это не конфликт версий, если переустановка node_modules что-либо меняет?

                      Если бы это был конфликт версий, то
                      1. Появление ошибки было бы связано с управлением зависимостями. А оно не было связано. Никто никаких новых модулей не ставил, не удалял, вообще не трогал ничего, связанного с модулями. И файлы вне рабочей области не трогал.
                      2. Простая переустановка модулей ничего бы не чинила. Поскольку их никто не трогал, то ставятся ровно те же модули, который и были до этого. А поскольку ошибка была очень устойчивой: проявлялась в течении всего проекта у всех фронтендеров, то это точно не конфликт версий.

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

                      Так что единственный подозреваемый — фреймворк.

                      Во Vue встроен полтергейст?

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

                        Я полагаю ошибка тут. Как именно вы переустанавливали зависимости? Случаем не посредством npm install. Если да, то вы ошибаетесь и зависимости установятся не те же самые.


                        Будь это баг платформы, это быстро бы появилось в ишуях платформы и не работало бы у всех.

                        Неа. Не у всех. Если баг мутный то для его воспроизведения нужно чтобы совпало очень много факторов — конкретная комбинация конкретных пакетов и конкретная платформа. К сожалению даже в MacOS и Linux инструменты работают не полностью идентично. Это сильно усложняет разбор полётов.

                          0
                          Нет. Они локаются через package-lock.json. А значит, ставятся ровно те же самые версии.
                          Кроме того, вы не внимательно читали. Смотрите.
                          0. Никто зависимости не трогает.
                          1. Возникает ошибка.
                          2. Ее чинят переустановкой зависимостей.
                          3. Через какое-то время снова возникает ошибка. И опять зависимости никто не трогал.

                          Не у всех. Если баг мутный то для его воспроизведения нужно чтобы совпало очень много факторов — конкретная комбинация конкретных пакетов и конкретная платформа.

                          У ноды/бабеля миллионы пользователей. Это очень популярное ПО. Если не было заведено ошибки, очень вероятно, что ее не было.

                          В общем, я вам точно говорю. Три человека над ней билось несколько дней. Это проблема фреймворка.
                            0

                            Я пожалуй задам ещё раз свой вопрос. Как именно вы переустанавливаете зависимости? Посредством 'npm install'? Несмотря на локающиеся зависимости в package-lock.json они им, тем не менее, не используются. И он ставит другие зависимости. Вот если вы использовали npm ci, то это было бы уже интересно.


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


                            У ноды/бабеля миллионы пользователей. Это очень популярное ПО. Если не было заведено ошибки, очень вероятно, что ее не было.

                            У npm бесчисленное количество глупых багов. И они годами не чинятся. Я уже даже перестал подписываться на них на гитхабе. Это ОЧЕНЬ проблемный инструмент. Вероятно, что ваша проблема там имеет не 1 ишью, а сразу штук 5 :)


                            Три человека над ней билось несколько дней

                            Вот адресуйте мой вопрос выше всем троим. Возможно вы удивитесь.

                              0
                              Да, конечно. Это же очевидно.

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

                              Ну, так это означает, что дело не в зависимостях.
                                0
                                Ну, так это означает, что дело не в зависимостях.

                                Если причиной бага является сочетание зависимостей и баг в npm, то это означает что дело в том числе и в зависимостях (косвенно). А главное не во Vue.

                              0

                              И пожалуй добавлю откуда у вас столько минусов выше. Вы обвиняете библиотеку в том, что она является источником багов, которые лечатся её переустановкой. Библиотеки. Переустановкой. Вы понимаете насколько забавно это звучит? Кусок кода глючит со временем, но когда вы его накатываете (по вашим словам) абсолютно тем же куском кода, то он не глючит. Шта? Я вам гарантирую что у вас что-то отличается в этих двух случаях. Либо какие-нибудь кеши в node_modules/.cache, либо зависимости ставятся другие (хоть вы и считаете, что те же самые), либо какие-нибудь хитрости с npm link, ручными симлинками, сайд эффектами на post install каких-нибудь пакетов (которые могут к примеру иметь какие-нибудь свои кеши).


                              Наткнувшись на такую проблему в будущем возмите md5 от "до" и от "после". Они либо у вас не сойдутся, либо проблема переустановкой не лечится.


                              Т.е. вероятность того что исполняемая часть Vue является источником проблемы и содержит "адовые баги" скорее наименее вероятный сценарий. Но вы это заявляете весьма уверенно :)

                                +1
                                Не только vue. Там приложение было на vuex.

                                Да, очевидно, что это какая то беда не буквально с самой библиотекой, а со всей экосистемой, ассоциированной с ней.

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

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

                                  Кажется вы совсем не читаете то, что я пишу, и у вас, каким-то магическим образом, снова виновата "экосистема" Vue. А в качестве аргумента "ни в реакте, ни в бэкбоне таких адских проблем не было". Это уже какая-то религия. За сим я удаляюсь из дискуссии, sorry :)

                                    0
                                    А я вас и не приглашал со мной дискутировать. Я просто поделился своим опытом, а вы почему-то со мной начали спорить и что-то доказывать.
                  0
                  [Данные удалены]
                    0
                    Если вакансий станет больше на Vue чем на React тогда стоит переходить.
                      0
                      К сожалению попробовав Vue2+TS на одном из проектов и потом попробовав React+TS, я выяснил что в реакте с типизацией все намного лучше, проверяется даже JSX, чего в Vue я так и не смог достичь, в общем сплошная благодать.
                        +1

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

                          0
                          Как нет cli? Написано же, что рекомендуется использовать vue-cli. Документация на официальном сайте: cli.vuejs.org/ru/guide.

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

                          Автор, судя по биографии, разбирается во Vue весьма неплохо:
                          I'm a Vue Community Partner, curator of the weekly Vue.js Developers Newsletter, and the founder of vuejsdevelopers.com, an online community for web professionals who love Vue.js
                          0
                          Если переменная message прокидывается дальше как свойство (prop) в дочерние компоненты, то библиотека об этом помнит, и дочерние компоненты также будут автоматически перерисованы. Именно поэтому в библиотеке Vue нет нужды в методе жизненного цикла, аналогичном реактовскому shouldComponentUpdate.
                          Вы не поверите, но в Реакте всё то же самое, только можно выбирать между Stateless (перерисовывать при изменении пропсов) и Stateful (перерисовывать всегда), и к явному использованию shouldComponentUpdate это не имеет никакого отношения. Явно его переопределять нужно только для тонкой настройки того, когда нужно, а когда не нужно перерисовывать компонент, т.ч. причём тут автоматическая перерисовка детей — непонятно.
                            0
                            Перерисовка детей — наверное, автор имел ввиду, что в shouldComponentUpdate можно провести анализ пропсов и запускать/не запускать перерисовку. Таким образом, Vue сам проводит этот анализ и запускает там, где нужно
                              0
                              Так детям пропсы задаёт родитель, не выполнив рендер родителя, в общем случае нельзя узнать, что́ он там им передаст при рендере. А не-общие случаи — это тот самый Stateless компонент, который никогда не перерисовывается, и Stateful компонент без shouldComponentUpdate, который перерисовывается всегда.
                            0
                            Например, хук created из примера выше запускается тогда, когда готово состояние (state) компонента, но до того, как компонент прикрепляется к странице. Аналог из мира React — getDerivedStateFromProps.

                            Но есть одна большая разница: в библиотеке Vue нет аналога реактовского shouldComponentUpdate. В этом нет необходимости ввиду наличия в Vue системы реактивности.

                            Здесь неточности. Конструктор в React (ранее — componentWillMount) — это aналог created, выполняется для инстанса единожды. А getDerivedStateFromProps выполняется многократно, ближайший аналог в Vue — watch, также может быть не нужен из-за реактивности.
                              –1
                              Для изменения состояния в Vue вам не нужно вызывать отдельный метод this.setState, как это делается в React. Вы просто пишете изменения напрямую:

                              // React
                              this.setState({ message: 'Hello World' });
                              // Vue
                              this.message = 'Hello World';


                              во VueJS так делать нельзя. Изменять состояние нужно вот так:
                              Vue.set(this, 'message', 'Hello World')


                              иначе будут проблемы с реактивностью
                                +1
                                во VueJS так делать нельзя.

                                Можно и нужно.

                                Если в секции data компонента объявлена переменная message:
                                data() {
                                  return {
                                    message  = '',
                                  }
                                }
                                

                                то

                                this.message = 'Hello World'; 

                                будет работать.
                                  –1
                                  в документации говорится обратное. Если изменять значение тем способом которым вы говорите, то VueJS может не отловить изменения значений.
                                    +1
                                    В документации сказано:
                                    Vue не может обнаружить добавление или удаление свойства. Так как Vue добавляет геттер/сеттер на этапе инициализации экземпляра, свойство должно присутствовать в объекте data для того чтобы Vue преобразован его и сделал реактивным.

                                    О чём я и написал выше. И это стандартный способ работы с реактивными свойствами во Vue.
                                    Ваш же комментарий — это к случаю:

                                    Во Vue нельзя динамически добавлять новые корневые реактивные свойства в уже существующий экземпляр. Тем не менее, можно добавить реактивное свойство во вложенные объекты, используя метод Vue.set(object, propertyName, value)

                                      0
                                      в документации говорится обратное

                                      Не говорится. Нет здесь никакой магии. Vue2 использует getter-ы и setter-ы. Это позволяет отлавливать и трекать все обращения в computed-контексте, и позволяет трекать все изменения. Но вот чего нельзя делать, так это пытаться присвоить значение туда, где ничего и не было. Потому что Vue2 заранее определяет какие поля будут observable, а какие нет. Во Vue3 будут Proxy, там можно будет даже это.


                                      Скажите, а вы правда во всём своём коде пишете Vue.set? :-)

                                  0

                                  … Возможность писать в стиле jQuery, ну все перехожу.

                                    +1
                                    create-create-app…
                                    — ошибка?
                                    — ошибка.

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