id: ecosystem-vue title: single-spa-vue

sidebar_label: Vue

single-spa-vue是一个针对vue项目的初始化、挂载、卸载的库函数,可以实现single-spa注册的应用生命周期函数等功能,详情请查看single-spa-vue的github

single-spa-vue is a helper library that helps implement single-spa registered application lifecycle functions (bootstrap, mount and unmount) for use with Vue.js. Check out the single-spa-vue github.

入门案例

先看一个功能完整的案例 coexisting-vue-microfrontends.

功能更加丰富的案例

https://coexisting-vue-microfrontends.surge.sh

安装

使用Vue CLI的项目

vue-cli-plugin-single-spa 将会把所有的事情都做好.

  1. vue add single-spa

这个CLI(控制台命令行接口)插件将会做下面的事情:

  1. 修改webpack配置,从而使你的项目适用于一个single-spa项目或是一个子应用。
  2. 安装single-spa-vue.
  3. 修改你的main.jsmain.ts文件,从而使你的项目适用于一个single-spa项目或是一个子应用。
  4. 添加set-public-path.js,从而有序地使用systemjs-webpack-interop来设置你的应用的public path。

没有使用Vue CLI的项目

  1. npm install --save single-spa-vue

你可以通过选择引入<script src="https://unpkg.com/single-spa-vue"></script>到你的html文件中,就可以得到singleSpaVue全局变量

用法

如果没有安装过的话,请安装systemjs-webpack-interop

npm install systemjs-webpack-interop -S

在和项目目录同级的位置新建set-public-path.js文件作为你的main.js/ts

  1. import { setPublicPath } from 'systemjs-webpack-interop';
  2. setPublicPath('appName');

将你的应用的入口文件改成如下内容:

Note that if you are using the Vue CLI Plugin, your main.ts or main.js file will be updated with this code automatically and the set-public-path.js file will automatically be created with the app name being your package.json’s name property.

If you want to deal with your Vue instance, you can modify the mount method by following this. mount method will return Promise with Vue instance after v1.6.0.

  1. const vueLifecycles = singleSpaVue({...})
  2. export const mount = props => vueLifecycles.mount(props).then(instance => {
  3. // do what you want with the Vue instance
  4. ...
  5. })

Vue 2

For Vue 2, change your application’s entry file to be the following:

  1. import './set-public-path';
  2. import Vue from 'vue';
  3. import App from './App.vue';
  4. import router from './router';
  5. import singleSpaVue from 'single-spa-vue';
  6. const vueLifecycles = singleSpaVue({
  7. Vue,
  8. appOptions: {
  9. render(h) {
  10. return h(App);
  11. },
  12. router,
  13. },
  14. });
  15. export const bootstrap = vueLifecycles.bootstrap;
  16. export const mount = vueLifecycles.mount;
  17. export const unmount = vueLifecycles.unmount;

注意:如果你正在使用Vue CLI插件,你的main.tsmain.js文件将会被自动更新为上面这段代码,set-public-path.js文件也将自动被创建,你的应用的名字将作为package.json文件中name属性的值

如果你想要获取到vue实例做一些操作,你可以通过如下指引修改mount方法。mount方法将会以Promise的形式返回Vue对象,该功能仅限于v1.6.0版本之后

Vue 3

For Vue 3, change your application’s entry file to be the following:

  1. import './set-public-path';
  2. import { h, createApp } from 'vue';
  3. import singleSpaVue from '../lib/single-spa-vue.js';
  4. import App from './App.vue';
  5. const vueLifecycles = singleSpaVue({
  6. createApp,
  7. appOptions: {
  8. render() {
  9. return h(App, {
  10. props: {
  11. // single-spa props are available on the "this" object. Forward them to your component as needed.
  12. // https://single-spa.js.org/docs/building-applications#lifecyle-props
  13. name: this.name,
  14. mountParcel: this.mountParcel,
  15. singleSpa: this.singleSpa,
  16. },
  17. });
  18. },
  19. },
  20. });
  21. export const bootstrap = vueLifecycles.bootstrap;
  22. export const mount = vueLifecycles.mount;
  23. export const unmount = vueLifecycles.unmount;

依赖共享

出于性能上的考虑,Vue、Vue Router以及其他较大的库,最好使用相同的版本

Custom props

Single-spa custom props can be passed to your root component like so:

  1. // main.js
  2. const vueLifecycles = singleSpaVue({
  3. Vue,
  4. appOptions: {
  5. render(h) {
  6. return h(App, {
  7. props: {
  8. mountParcel: this.mountParcel,
  9. otherProp: this.otherProp,
  10. },
  11. });
  12. },
  13. router,
  14. },
  15. });
  1. // App.vue
  2. <template>
  3. <button>{{ otherProp }}</button>
  4. </template>
  5. <script>
  6. export default {
  7. props: ['mountParcel', 'otherProp'],
  8. }
  9. </script>

Shared dependencies

要实现不同应用间的依赖共享,添加你想要共享的依赖作为webpack externals。然后使用 一个工作在浏览器中的模块加载工具,比如systemjs,来为single-spa中的每个项目提供这些共享的依赖,将vue以及其他库添加到import map中。

如下案例给出一个import map的案例,可以作为参考: coexisting-vue-microfrontends的 index.html文件

依赖共享是被强烈建议的。详细的原因可以查看recommended setup for single-spa

使用Vue CLI的情况下共享的配置

  1. // vue.config.js
  2. module.exports = {
  3. chainWebpack: config => {
  4. config.externals(['vue', 'vue-router']);
  5. },
  6. };

未使用Vue CLI的情况下共享的配置

  1. // webpack.config.js
  2. module.exports = {
  3. externals: ['vue', 'vue-router'],
  4. };

选项

当调用singleSpaVue(opts)时,所有选项都是通过opts参数传入single-spa-vue的

  • Vue: (必传项) 主Vue对象, 通常暴露在window对象上,或通过require('vue') import Vue from 'vue'获得
  • appOptions: (必传项) 类型为Object对象类型,用来实例化Vue应用。appOptions将直接透传为Vue构造函数实例化时的初始化参数new Vue(appOptions)。需要注意:如果你没有传el选项,插件就会自动创建一个div,并作为一个Vue项目的默认容器附加到DOM中。
  • loadRootComponent: (非必传,用于取代appOptions.render) 在懒加载时有用,一个以root component为成功回调参数的Promise对象。

可以用appOptions.el配置single-spa要挂载到哪个dom元素上,:

  1. const vueLifecycles = singleSpaVue({
  2. Vue,
  3. appOptions: {
  4. render: h => h(App),
  5. el: '#a-special-container',
  6. },
  7. });

作为一个single-spa应用

想要创建一个single-spa应用,只需要从appOptions中去掉el选项,如此一来,dom元素将需要应用的开发者来指定,除此之外的其他选项都应该和上述案例保持一致

自定义数据

single-spa 自定义数据通常以appOptions.data添加到你的App组件中,可以通过vm.$data得到。参考Vue文档中相关的说明获取更多内容。

single-spa custom props are added to your App component as appOptions.data, and are accessible via vm.$data. See this Vue documentation for more information on appOptions.data.