Почему ты бы так поступил?

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

Я скажу вам почему

Виджет Vue здесь был плагином для тегов, который мы должны интегрировать на разных платформах с техническими стеками, включая Backbone.js и React.js.

Теперь вы можете спросить:

Почему тогда вы не создали его на React?

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

Для протокола, я фанат React

Итак, продолжим рассказ

Моей задачей было интегрировать плагин тегов в 5 типов форм на тестовой платформе, которая сейчас находится в разработке ⚒. Платформа предоставляет 5 типов форм для создания вопросов (вопросы с несколькими правильными, однократными, числовыми, кодированными и открытыми текстами).

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

Перейдем к интеграции

Как и любой другой разработчик, моим первым побуждением было погуглить, делал ли кто-нибудь это раньше. Я был достаточно уверен, что найдется кто-то, кто сталкивался с той же проблемой. К сожалению, мне не удалось найти ни одного примера. Что? !!! Это основная причина, по которой я пишу этот блог.

Что теперь?

Я знал, что единственное место, где я могу получить помощь, - это документы Vue. К моему счастью, документация Vue была такой же четкой, как рамка на двери Моники. Для всех тех магглов (тех, кто не является сумасшедшими фанатами F.R.I.E.N.D.S), это означает кристально чистую информацию.

Для начала мне нужен был способ создать экземпляр приложения Vue и смонтировать его в div в компоненте плагина тегов React. Кстати, React не отображает виджет Vue, если вы напрямую используете его в HTML-коде рендеринга, как это 👇

function TaggingPlugin(){
//react tagging plugin component
...
return <vue-tagging-plugin/> // vue tagging component
}

Поэтому мне пришлось программно создать экземпляр Vue, вот так 👇

Не волнуйтесь, я объясню это подробно

var vm = new Vue({   // options })

Это создает экземпляр приложения Vue и монтирует его на el, который является корневым узлом HTML.

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

render: function(h) { // h = createElement
     return h(window.taggingPlugin, {
        props: this.props
     });
}

В API рендеринга Vue передается функция createElement. Это создает HTML, насыщает его данными и реквизитами, если они есть, и, наконец, возвращает узел Vue, который затем добавляется в DOM. Первым аргументом createElement может быть имя тега HTML, параметр компонента или любая асинхронная функция, которая разрешает (которая в нашем случае является экземпляром, который мы создали) для любого из вышеперечисленных. Второй аргумент - это объект с атрибутами, которые вы используете в обычном определении компонента Vue, в моем случае это реквизиты для виджета.

Теперь у нас есть свойство data 👇

data() {     
    return {
          ...     
          props: {
          }
    }
}

Опора данных во Vue в основном эквивалентна состоянию компонента React. Теперь вам может быть интересно, почему я создал объект props в данных и использовал его, в свою очередь, для передачи его в свойство Vue createElement's. Итак, причина в том, что созданный мной виджет является дочерним по отношению к корневому экземпляру Vue, и это также был лучший способ передать данные из корня самого приложения, вместо того, чтобы напрямую вводить реквизиты из компонента React.

return h(window.taggingPlugin, {          
     props: this.props     
});

this здесь - это экземпляр Vue, поэтому мы можем легко получить доступ к данным приложения Vue. Поэтому всякий раз, когда мне нужно было обновить опору id в виджете Vue из компонента React, я делал что-то вроде этого 👇

useEffect(() => {
     window.taggingInstance.props.config.componentId = id;
}, [id]);

Ну та часть, где все сочетается 👇

Это компонент React после всей интеграции с виджетом Vue.

Кроме того, JFYI, чтобы taggingPlugin был доступен в окне, вам необходимо добавить файл js сборки виджета, файл CSS и файлы пакета Vue в свой index.html файла Приложение React.

Заключение

То, что я не нашел никакого решения, когда я впервые искал это в Google, стало поворотным моментом. В противном случае я бы не изучил замечательные документы Vue и не получил бы более глубокого понимания внутреннего устройства Vue - того, как визуализируется компонент, как работает поток данных, и, прежде всего, спешка с поиском выхода для решения такой проблемы. интересная проблема. Я уверен, что будут лучшие и эффективные способы сделать это. Если есть такие ссылки или методы, пожалуйста, добавьте их в комментарии.