记录vue2和vue3中异步加载远程组件的不同实现

背景1:公司产品有多个,有sso login功能,即一个登录页面可以跳转多个产品。另外这个统一的登录页面也包含了头部header,可以跳转到公司人意其他内部产品,也有登出功能。
需求:需要在新开发的一个产品接入这个header,实现统一header。
总体技术实现:远程加载路径为「APP_XX_HEADER_URL」的header js文件,在vue template中能够使用 调用。
不足:解决问题的时间久远,忘记当时遇到什么问题和一些思考过程了,这里只是记录最终的解决方案。

<template>
   <component :is="type" :id-token="dxToken" @logout="apLogout"></component>
</template>

<script>
/* eslint-disable consistent-return */
import Vue from 'vue';
import { mapState } from 'vuex';
import SettingsService from '@/services/settings.js';
import Store from '@/store/index.js';

export default Vue.extend({
  name: 'DaoHeader',
  data() {
    return {
      type: 'div',
    };
  },
  methods: {
    getTokenInfo() {
      SettingsService.getDxToken().then(res => {
        const { id_token } = res?.data || {};
        this.$store.commit('auth/saveDxToken', id_token);
      });
    },
    setHeaderComponent(href) {
      if (!href) return;
      const Navigation = {};
      const url = Store.state.auth.dxUrl;
      const APP_DX_ARCH_HEADER_URL = `${url}/header/DxHeader.umd.min.js`;
      if (!APP_DX_ARCH_HEADER_URL) {
        return Navigation;
      }
      return import(/* webpackIgnore: true */ APP_DX_ARCH_HEADER_URL)
        .then(() => {
          const { DxHeader = Navigation } = window.DxHeader || {};
          Vue.component('dxHeader', DxHeader);
          this.type = 'dxHeader';
          return DxHeader;
        })
        .catch(() => {
          return Navigation;
        });
    },
    apLogout() {
      SettingsService.logout().then(() => {
        this.$message.success('登出成功');
        this.getTokenInfo();
      });
    },
  },

  computed: {
    ...mapState('auth', ['dxToken', 'dxUrl']),
    isAuth() {
      const { dxToken, dxUrl } = this;
      return { dxToken, dxUrl };
    },
  },

  watch: {
    isAuth: {
      deep: true,
      immediate: true,
      handler(val) {
        const { dxUrl, dxToken } = val;
        if (!dxUrl || !dxToken) return;
        this.setHeaderComponent(dxUrl);
      },
    },
  },
});
</script>

背景2,远程组件使用的是vue2,但本地使用的是vue3,怎么办?

<template>
  <div id="dx" :class="type"></div>
</template>

<script setup>
import { Vue2InVue3 } from '@efox/emp-vuett';
import { render, ref, createVNode, getCurrentInstance } from 'vue';
import { useStore } from 'vuex';
import SettingsService from '@/service/settings.js';
const store = useStore();
const idToken = ref(store.state.settings.dxToken);
import(`${store.state.settings.dxUrl}/header/DxHeader.umd.min.js`);
const $message =
  getCurrentInstance().appContext.config.globalProperties.$message;
const logout = () => {
  SettingsService.logout()
    .then(() => {
      $message.success('登出成功');
      location.reload();
    })
    .catch((e) => {
      console.log(e);
    });
};

setTimeout(() => {
  const AsyncComp = window.DxHeader || { DxHeader: {} };
  const container = document.createElement('div');
  const idToken = store.state.settings.dxToken;
  const header = createVNode(Vue2InVue3(AsyncComp.DxHeader, 'dx'), {
    'id-token': idToken,
    logout,
  });
  render(header, container);
}, 1000);
</script>

主要是借助国内某个大兄弟开源的库Vue2InVue3,挺好使 ^ ^

你可能感兴趣的:(踩坑笔记,vue,javascript,javascript,vue.js,前端)