Vue.JS - микро-интерфейс

Наша команда разрабатывает большой проект, и мы хотим создать большое приложение с несколькими формами, панелями и функциями. Один монолитный SPA будет сложным. Итак, мы обсуждаем подход "архитектора микро-фронтендов". Цель состоит в том, чтобы создать родительский SPA, который содержит несколько дочерних SPA. Все SPA должны иметь одинаковую структуру (vueJS).

Идея этого подхода ( https://micro-frontends.org/)

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

Мы нашли некоторые реализации этого подхода

1) https://micro-frontends.org/

2) CanopyTax с одиночным спа -> https://github.com/CanopyTax/single-spa

Что мы хотим использовать в нашем интерфейсе:

  • вю

  • вя-маршрутизатор

  • вя-ресурс

  • вя-погрузчик

  • WebPack

Наши вопросы:

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

- we are not sure how doable is it with VueJS
- there may already be example projects?

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

3) Можно ли установить Event-Bus между компонентами VueJS?

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

- Parent-Child Communication
- Child-Parent Communication

1 ответ

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

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

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

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

3) Можно ли установить Event-Bus между компонентами VueJS?

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

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

Лучший способ отправки данных из родительского компонента в дочерний - использование реквизита. Шаги: (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/vue@2.5.13/dist/vue.min.js"></script>

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

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

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/vue@2.5.13/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/vue@2.5.13/dist/vue.js"></script>

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

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

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

I have been curious looking for a quick way to implement the Micro-frontend architecture. Some good resources I found are at: https://micro-frontends.org/ and https://single-spa.js.org/, however the problem I had with them is setup complexity... I like to see results pretty fast. https://piral.io/ is still pretty much in development and it's mainly targeted for react, but here are my findings.

I was able to come up with an approach and hope to write an medium article on that soon, however for the time being

  1. You can build each part of your application as an independent WebComponent, with Vue, this article is a great place to start.
  2. You can use vue-router, and with dynamic route matching (e.g /apps/:app_name) you can load sub-applications as appropriate. Within each sub-app, you can as well have a routing system in place
  3. In recent browsers, there's BroadcastChannel which can be used to send messages across sub-apps. This could be resourceful.
  4. BroadcastChannel can handle bi-directional communication.

This approach works best if you want to:

  1. Have separate team use whatever tool they're most comfortable with.
  2. Add new apps, even in production without downtime.
Другие вопросы по тегам