24

我们的团队正在开发一个大型项目,我们希望构建一个具有多个表单、仪表板和功能的大型应用程序。一个单一的 SPA 会变得复杂。因此,我们讨论“微前端”架构的方法。目标是生成包含多个子 SPA 的父 SPA。所有 SPA 都应该使用相同的框架:vueJS。

背后的想法:微前端

  • Web 应用程序是由独立团队拥有的功能的组合
  • 一个团队有一个独特的业务领域
  • 该团队是跨职能的,从数据库到用户界面的端到端功能开发
  • 就像独立的系统

我们发现了一些支持这一点的实现:

  1. 微前端
  2. CanopyTax 的单一 SPA

我们想在前端使用VueJS(vue、vue-router、vue-resource、vue-loade、webpack)

问题

  1. 使用VueJS (标准 Vue 工具)实现复合 UI(即微前端)是否可行,是否有示例项目?
  2. 我们有不止一个页面,因此我们需要一个解决方案来从一侧导航到另一侧。我们如何实现页面转换
  3. 是否可以在 VueJS 组件之间建立事件总线?
  4. 我们如何实现组件之间的双向通信(父子,子父)?
4

2 回答 2

18

可行性:复合 UI

  1. 是否可以使用标准的 vue 工具创建基于 vue 的复合 UI(微前端)?

对的,这是可能的。您看到的几乎所有独立的 Vue 组件(vue-selectvue-slider-component甚至完整的“集合”组件,例如vuetifybootstrap-vuevue-material)都是使用开发的可重用(可组合)组件的示例标准的 Vue 工具。

页面转换:路由

  1. 我们有不止一个页面,因此我们需要一个解决方案来从一侧导航到另一侧。我们如何实现页面转换?

vue-router是完成这项工作的工具。它由核心团队开发,因此期待紧密的集成和强大的功能支持。

事件总线

  1. 是否可以在 VueJS 组件之间建立事件总线?

每个 Vue 实例都实现了一个事件接口。这意味着要在两个 Vue 实例或组件之间进行通信,您可以使用自定义事件。你也可以使用 Vuex(见下文)。

双向通信

  1. 我们如何实现组件之间的双向通信?

将数据从父组件发送到子组件的最佳方式是使用props。脚步:

  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>

您还可以获取子组件 ( s) 的引用并在它们上调用方法。ref

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 时,您不必将状态从父级传递到子级:所有这些都将从 Vuex 存储中获取它(某种“全局”反应变量)。这大大简化了应用程序的管理,值得一帖。


最后一点:如您所见,Vue 的一大优势是您可以轻松地原型化和测试功能。没有构建步骤,对原始 JS 的抽象很少。与其他框架相比,我想说这是一个重要的好处。

于 2018-03-10T01:20:41.690 回答
13

我一直很好奇寻找一种快速实现微前端架构的方法。我发现的一些好资源位于:

  • micro-frontends.org:用于构建具有多个团队的现代 Web 应用程序的技术、策略和配方,这些团队可以独立发布功能。
  • Single-SPA.js : 前端微服务的 Javascript 路由器

但是,我遇到的问题是设置复杂性。我喜欢很快看到结果。

海盗

Piral.io(遵循微前端架构的门户应用程序框架)仍在开发中,主要针对React(另一个 JS 前端框架)。

Vue 方法

我能够想出一个方法,并希望尽快写一篇关于它的中型文章,但是暂时

  1. 您可以使用 Vue 将应用程序的每个部分构建为独立的Web 组件。一个很好的起点是使用 Vue CLI 3 - Vue.js 开发人员创建和发布 Web 组件
  2. 您可以使用vue-router进行页面转换:通过动态路由匹配(例如/apps/:app_name),您可以根据需要加载子应用程序。在每个子应用程序中,您还可以拥有一个路由系统
  3. 作为 Event-Bus,最近的浏览器中有BroadcastChannel,可用于跨子应用发送消息。广播频道 API可能是资源丰富的。
  4. BroadcastChannel可以处理双向通信。

如果您想,上述方法效果最好:

  1. 让单独的团队使用他们最熟悉的任何工具。
  2. 添加新应用程序,即使在生产中也无需停机。
于 2019-07-20T21:58:50.940 回答