使用VueGenesis从零开始前端微服务开发(三)远程组件

1 引言

Genesis 框架微服务框架中,还有一个将组件作为独立服务部署,远程调用组件的功能。这里讲述如何开发share模块的远程组件并在其他服务中调用的方法。

准备上篇文章中的源码或者其他 Genesis 微服务架构的前端代码。

2 改造组件(e-mes-share)

2.1 添加组件路由

router.ts

2.2 修改组件暴露事件

暴露远程事件使用this.$root.$emit

3 远程调用(e-mes-home)

3.1 导入远程组件

import { RemoteView } from “@fmfe/genesis-remote”;
import axios from “axios”;

3.2 标签

      <remote-view
        v-if="RegionSelection"
        :key="RegionSelection.url"
        :clientFetch="() => fetch(RegionSelection, 'client')"
        :serverFetch="() => fetch(RegionSelection, 'server')"        
        @change="onRegionSelectionChange"
      />
1
2
3
4
5
6
7

3.3 定义远程组件元数据

interface RegionSelection {
  ssrname: string;
  url: string;
}
  computed: {
    RegionSelection() {
      return {
        ssrname: "e-mes-share",
        url: "/share/component/region-selection",
      };
    },
  },
1
2
3
4
5
6
7
8
9
10
11
12

3.4 远程组件调用方法

    async fetch(cmp: RegionSelection, type: string) {
      const res = await axios.get(`/api/${cmp.ssrname}/render`, {
        params: {
          // 远程组件调用路由模式必须是abstract,否则调用后回改变地址栏路由
          routerMode: "abstract",
          renderMode: type == "client" ? "csr-json" : "ssr-json",
          renderUrl: cmp.url,
          // 可以通过这个传递参数到远程组件
        },
      });
      if (res.status === 200) {
        return res.data;
      }
      return null;
    },
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

注意:路由模式abstract

3.5 远程组件事件处理函数

    onRegionSelectionChange(province,city,country) {
      console.log(province+"-"+city+"-"+country);
    },
1
2
3

3.6 完整代码

<template>
  <div class="home">
    <h2>首页</h2>
    <div>
      <remote-view
        v-if="RegionSelection"
        :key="RegionSelection.url"
        :clientFetch="() => fetch(RegionSelection, 'client')"
        :serverFetch="() => fetch(RegionSelection, 'server')"        
        @change="onRegionSelectionChange"
      />
    </div>
  </div>
</template>
<script lang="ts">
import Vue from "vue";
import { RemoteView } from "@fmfe/genesis-remote";
import axios from "axios";

interface RegionSelection {
  ssrname: string;
  url: string;
}

export default Vue.extend({
  name: "home",
  components: {
    RemoteView,
  },
  computed: {
    RegionSelection() {
      return {
        ssrname: "e-mes-share",
        url: "/share/component/region-selection",
      };
    },
  },
  methods: {
    onRegionSelectionChange(province,city,country) {
      console.log(province+"-"+city+"-"+country);
    },
    async fetch(cmp: RegionSelection, type: string) {
      const res = await axios.get(`/api/${cmp.ssrname}/render`, {
        params: {
          routerMode: "abstract",
          renderMode: type == "client" ? "csr-json" : "ssr-json",
          renderUrl: cmp.url,
          // 可以通过这个传递参数到远程组件
        },
      });
      if (res.status === 200) {
        return res.data;
      }
      return null;
    },
    // methods end
  },
});
</script>
<style scoped>
</style>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61

4 总结

远程组件调用,主要是路由模式的改变以及事件需要暴露给服务提供者的$root。