Vue.JS для подхода Micro Frontend

Наша команда разрабатывает большой проект, и мы хотим создать большое приложение с множеством форм, панелей мониторинга и функций. Один монолитный СПА усложнился бы. Итак, мы обсуждаем подход архитектуры «микро-интерфейса». Цель состоит в том, чтобы создать родительский SPA, содержащий несколько дочерних SPA. Все SPA должны использовать одну и ту же структуру: vueJS.

Идея: Micro Frontend s

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

Мы нашли несколько реализаций, поддерживающих это:

  1. Micro Frontends
  2. Single-SPA CanopyTax

Мы хотим использовать VueJS в нашем интерфейсе (vue, vue-router, vue-resource, vue-loade, webpack)

Вопросов

  1. Возможен ли составной пользовательский интерфейс (например, Micro Frontend) с помощью VueJS (стандартные инструменты Vue), есть ли примеры проектов?
  2. У нас более одной страницы, поэтому нам нужно решение для перехода с одной стороны на другую. Как мы можем реализовать переходы между страницами?
  3. Можно ли установить шину событий между компонентами VueJS?
  4. Как мы можем реализовать двунаправленную связь между компонентами (родитель-потомок, потомок-родитель)?

person René    schedule 09.03.2018    source источник
comment
Думаю, ваш вопрос должен быть больше по теме разработки программного обеспечения, поскольку вы вообще не показываете здесь код.   -  person Patrick Mevzek    schedule 09.03.2018
comment
Ответ на все эти вопросы - да. Vue хорошо подходит для микро-интерфейса. Вы хотите добавить vuex в свой список используемых библиотек vue, и это также позаботится о вашей шине событий. Двунаправленная связь осуществляется посредством передачи свойств от родителя к дочернему и передачи событий от дочернего элемента к родительскому. Но вы можете использовать автобус и для этого.   -  person skribe    schedule 09.03.2018
comment
ПРИВЕТ, Мне нужна такая же архитектура для большого большого приложения, которое мы собираемся создать на VueJS, поэтому вы имеете в виду, что если у меня есть 20 модулей, например, тогда лучше создать 20 приложений VueJS (каждое по модулю?), Если это правда, как сделать вы разделяете управление состоянием между ними, или как вы используете компонент, который находится в другом приложении VueJS, из другого приложения VueJS? Все это звучит действительно очень интересно. Спасибо   -  person VAAA    schedule 26.08.2018
comment
Что касается микро-интерфейсов, вы можете подумать о смешивании нескольких интерфейсных технологий (Vue, React, веб-компоненты ...) в зависимости от того, что лучше всего подходит для команды / домена, связанного с микро-интерфейсом. Это также объясняется здесь.   -  person Rémi Bantos    schedule 13.11.2018


Ответы (2)


Осуществимость: составной интерфейс.

  1. Можно ли создать составной UI (микро-интерфейс) на основе vue с помощью стандартных инструментов vue?

Да, это возможно. Практически любой независимый Vue-компонент, который вы видите опубликованным (vue-select, vue-slider-component и даже полные наборы компонентов, такие как vuetify, bootstrap-vue или vue-material являются примерами многоразовых (компонуемые) компоненты, разработанные с использованием стандартных инструментов Vue.

Переходы страниц: маршрутизация

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

Инструмент для этой работы - vue-router. Он разработан основной командой, поэтому ожидайте тесной интеграции и отличной поддержки функций.

Ивент-автобус

  1. Можно ли установить шину событий между компонентами VueJS?

Каждый экземпляр Vue реализует интерфейс событий. Это означает, что для связи между двумя экземплярами или компонентами Vue вы можете использовать Пользовательские события. Вы также можете использовать Vuex (см. Ниже).

Двунаправленная связь

  1. Как мы можем реализовать двунаправленную связь между компонентами?

Лучший способ отправить данные от родительского компонента к дочернему - использовать реквизит. Шаги:

  1. Объявите props (массив или объект) в дочернем
  2. Передайте его ребенку через <child :name="variableOnParent">.

См. Демонстрацию ниже:

Vue.component('child-comp', {
  props: ['message'], // declare the props
  template: '<p>At child-comp, using props in the template: {{ message }}</p>',
  mounted: function () {
    console.log('The props are also available in JS:', this.message);
  }
})

new Vue({
  el: '#app',
  data: {
    variableAtParent: 'DATA FROM PARENT!'
  }
})
<script src="https://unpkg.com/[email protected]/dist/vue.min.js"></script>

<div id="app">
  <p>At Parent: {{ variableAtParent }}</p>
  <child-comp :message="variableAtParent"></child-comp>
</div>

Вы также можете получить ссылки для дочерних компонентов ( refs) и вызывать на них методы.

Vue.component('my-comp', {
  template: "#my-comp-template",
  props: ['name'],
  methods: {
    saveMyComp() {
      console.log('Saved:', this.name);
    }
  }
})

new Vue({
  el: '#app',
  data: {
    people: [{name: 'Bob'}, {name: 'Nelson'}, {name: 'Zed'}]
  },
  methods: {
    saveChild(index) {
      this.$refs.myComps[index].saveMyComp();
    }
  }
});
<script src="https://unpkg.com/[email protected]/dist/vue.min.js"></script>

<div id="app">
  <div v-for="(person, index) in people">
    <button @click="saveChild(index)">saveMyComp</button>
    <my-comp :name="person.name" ref="myComps"></my-comp>
  </div>
</div>

<template id="my-comp-template">
    <span> {{ name }} </span>
</template>

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

var parent = {
  template: '<div><child :content.sync="localContent"></child><br>At parent: {{ localContent }}</div>',
  props: ['content'],
  data() {
    return {
      localContent: this.content
    }
  }
};

var child = {
  template: '<div>At child: {{ content.value }}<button @click="change">change me</button></div>',
  props: ['content'],
  methods: {
    change() {
      this.$emit('update:content', {value: "Value changed !"})
    }
  }
};

Vue.component('child', child);
Vue.component('parent', parent);

new Vue({
  el: '#app'
});
<script src="https://unpkg.com/[email protected]/dist/vue.js"></script>

<div id="app">
  <parent :content="{value:'hello parent'}"></parent>
</div>

Vuex

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


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

person acdcjunior    schedule 10.03.2018
comment
Отличный ответ, случайно зашел зайти, хотя оно того стоило !. - person Jaya; 10.03.2018
comment
@acdcjunior ... отличная работа! Спасибо за подробный и обоснованный ответ. Мы приняли ваши предложения и уже успешно их протестировали. VueRouter и Vuex оказались очень полезными. Будем и дальше придерживаться подхода… - person René; 20.03.2018
comment
Хотя OP, возможно, не имел в виду дочерний SPA, мне любопытно, каков будет ответ для этого контекста. Контекст этого ответа на самом деле касается только объединения компонентов, а не SPA. - person dispake; 27.07.2019
comment
Исчерпывающий ответ, конкретно демонстрирующий все рассматриваемые вопросы ⭐️ Я предложил отредактировать, чтобы улучшить структуру. - person hc_dev; 23.03.2021

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

  • micro-frontends.org: методы, стратегии и рецепты для создания современного веб-приложения с несколькими командами, которые могут поставлять функции независимо.
  • Single-SPA.js: маршрутизатор Javascript для интерфейсных микросервисов

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

Пираль

Piral.io (фреймворк для портальных приложений, следующих за архитектурой микрофронтендов) все еще находится в стадии разработки и в основном ориентирован на React (еще один интерфейс-фреймворк JS).

Подход Vue

Я смог придумать подход и надеюсь вскоре написать об этом статью среднего размера, однако на данный момент

  1. Вы можете создать каждую часть своего приложения как независимый веб-компонент с помощью Vue. Отличное место для начала - Создание и публикация веб-компонентов с помощью Vue CLI 3. - Разработчики Vue.js.
  2. Вы можете использовать vue-router для переходов между страницами: с динамическим сопоставлением маршрутов (например, /apps/:app_name) вы можете загружать субприложения по мере необходимости. В каждом дополнительном приложении вы также можете иметь систему маршрутизации.
  3. В качестве Event-Bus в последних версиях браузеров есть BroadcastChannel, который может использоваться для отправки сообщений во вложенных приложениях. Может оказаться полезным Broadcast Channel API.
  4. BroadcastChannel может обрабатывать двунаправленную связь.

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

  1. Отдельная команда должна использовать тот инструмент, который ей удобнее всего.
  2. Добавляйте новые приложения, даже если они находятся в рабочем состоянии, без простоев.
person amustapha    schedule 20.07.2019
comment
Я думаю, что это пока правильный ответ. - person Ramon Gonzalez; 20.08.2019
comment
Я хотел бы указать людям еще на это чтение, где эта тема микрофронтенда довольно хорошо объяснена: martinfowler .com / article / micro-frontends.html - person Ramon Gonzalez; 24.08.2019
comment
piral.io - это супер круто - если бы оболочка приложения работала за считанные минуты, развернула ее в корзине S3, настроила канал с feed.piral.io и развернул мои первые модули. Все за один проход! Однако я полностью использовал React. - person Florian Rappl; 09.11.2019
comment
@amustapha - у меня возникла проблема в моем микро-приложении vue с тем, что вы написали в пункте № 2, т.е. вы можете использовать vue-router, а с динамическим сопоставлением маршрутов (например, / apps /: app_name) вы можете загружать под-приложения по мере необходимости. В каждом подприложении вы также можете иметь систему маршрутизации ... Фактически мой веб-компонент vue, использующий маршрутизатор vue для управления своей навигацией, и когда я использую этот веб-компонент в приложении оболочки vue, которое также использует свой собственный vue роутер. он не запускает приложение оболочки и выдает ошибку: Uncaught TypeError: невозможно переопределить свойство: $ router. Что я могу здесь сделать? спасибо в нареч. - person Atul; 01.02.2020
comment
@amustapha я также помещаю свою информацию здесь stackoverflow.com/questions/60024245/ - person Atul; 02.02.2020
comment
Broadcast Channel не поддерживается Safari, здесь большой недостаток - person petitkriket; 08.04.2021
comment
Привет, @petitkriket, я считаю, что есть обратная совместимость, которая возвращается к локальному хранилищу в старых браузерах. Я не могу сразу это рассмотреть, но с этим можно поработать: npmjs.com / пакет / broadcastchannel-polyfill - person amustapha; 19.04.2021