您现在的位置是:首页 >技术教程 >基于micro-app+vue-element-admin实现微前端网站首页技术教程

基于micro-app+vue-element-admin实现微前端

笑到世界都狼狈 2023-07-10 12:00:03
简介基于micro-app+vue-element-admin实现微前端

简述

本文是在对之前搭建和学习micro-app的基础上的进一步研究学习。
因为我们目前项目使用的框架是vue-element-admin,所以还需要研究一下micro-app在vue-element-admin的使用方法。
关于micro-app在vue-element-admin的实现,百度什么也没找到,只能按照之前搭建的micro-app的基础模仿着搭建着自己搞。

接下来开始搭建

1、创建项目目录

关于目录的创建,新增文件夹micro-app-element,文件夹中有三个vue-element-admin项目:vue-element-base(基座)、vue-element-first(子应用1)、vue-element-second(子应用2)
具体如下图所示:
在这里插入图片描述
其中vue-element-base(基座)、vue-element-first(子应用1)、vue-element-second(子应用2)是创建的vue-element-admin项目,如果不会创建,可参考
我这边是之前创建好的现成的包,拿过来直接解压了三个修改了一下名称,一个基座两个个子应用,项目内容大致如下
在这里插入图片描述

2、基座配置

我这边按之前搭建micro-app的过程一步步来,只是把之前的创建项目的过程省略掉了,现在直接用现成的vue-element-admin,搭建参考
注:接下来的配置都是在vue-element-base中进行配置的

2-1、配置vue.config.js

之前搭建的时候配置了localhost和port端口,vue-element-admin看情况是封装好的,不用修改太多
在这里插入图片描述

2-2、安装micro-app

安装micro-app插件,安装在base目录下

npm install @micro-zoe/micro-app --save

安装完成后,可以在基座package.json中看到安装好的@micro-zoe/micro-app,如下图所示:
在这里插入图片描述

2-3、配置micro

创建micro配置文件夹,配置config和index
在这里插入图片描述
config.js

/**
* 子应用前缀
*/
export const CHILD_PREFIX = 'child'


/**
* 子应用地址
*/
export const MICRO_APPS = [
  { name: 'first-child', url: `http://localhost:9528` },
  { name: 'second-child', url: `http://localhost:9529` }
]


/**
* 全局资源
*/
export const GLOBAL_ASSETS = {
  js: [],
  css: []
}

index.js

import microApp from '@micro-zoe/micro-app'
import * as config from './config'


/** 启用 micro */
microApp.start({
  preFetchApps: config.MICRO_APPS,
  globalAssets: config.GLOBAL_ASSETS
})

2-4、修改main.js

修改main.js。引入micro

import './micro'

在这里插入图片描述

2-5、修改AppMain.vue

AppMain.vue修改(这个我在项目里找了一下,找到系统主体部分是写在AppMain.vue中的。按照之前搭建时的思路进行了一些修改)
差不多对AppMain.vue进行了如下图所示修改:
在这里插入图片描述

完整代码:

<template>
  <section class="app-main">
    <transition name="fade-transform" mode="out-in">
      <keep-alive :include="cachedViews">
        <!--element-ui视图部分,这边可以判断是不是子应用,如果子应用显示micro-app,
        否则直接显示router-view-->
        <micro-app
          v-if="isChild"
          v-bind="micro"
          destory
        />
        <router-view v-else :key="key" />
      </keep-alive>
    </transition>
  </section>
</template>


<script>
import { MICRO_APPS, CHILD_PREFIX } from '../../micro/config'


export default {
  name: 'AppMain',
  data() {
    return {
      isChild: false,    /** 是否为子模块 */
      micro: {
        url: '',     /** 子模块地址 */
        key: '',     /** vue 标签的 key 值,用于不同子模块间的切换时,组件重新渲染 */
        name: '',    /** 子模块名称,唯一 */
        data: {},    /** 子模块数据 */
        baseroute: ''   /** 子模块数据 */
      },
      prefix: CHILD_PREFIX /** 子模块链接前缀 */
    }
  },
  computed: {
    cachedViews() {
      return this.$store.state.tagsView.cachedViews
    },
    key() {
      return this.$route.path
    }
  },
  watch: {
    $route(val) { /** 监听路由变化修改视图显示 */
      this.changeChild(val)
    }
  },
  created() {
    this.changeChild(this.$route)
  },
  methods: {
    /**
     * 获取子模块 url 和 name
     * */
    getAppUrl(name) {
      return MICRO_APPS.find(app => app.name === name) || {}
    },
    /**
     * 修改子视图显示
     * */
    changeChild(route) {
      const path = route.path.toLowerCase()
      const paths = path.split('/')


      // 判断是否为子模块,子模块有固定的前缀,在 micro/config 设置
      this.isChild = paths.length > 2 && paths[1] === CHILD_PREFIX


      if (this.isChild) {
        const app = this.getAppUrl(paths[2])


        this.micro = {
          ...app,
          data: { name: route.name },
          key: `${app.name}`,
          baseroute: `/${CHILD_PREFIX}/${paths[2]}`
        }
      }
    }
  }
}
</script>


<style lang="scss" scoped>
.app-main {
  /* 50= navbar  50  */
  min-height: calc(100vh - 50px);
  width: 100%;
  position: relative;
  overflow: hidden;
}


.fixed-header+.app-main {
  padding-top: 50px;
}


.hasTagsView {
  .app-main {
    /* 84 = navbar + tags-view = 50 + 34 */
    min-height: calc(100vh - 84px);
  }


  .fixed-header+.app-main {
    padding-top: 84px;
  }
}
</style>


<style lang="scss">
// fix css style bug in open el-dialog
.el-popup-parent--hidden {
  .fixed-header {
    padding-right: 15px;
  }
}
</style>

2-6、基座中配置子应用1路由

在基座中配置子应用1路由(vue-element-admin中有好多页面,随便找了两个配置子应用路由
在这里插入图片描述
在这里插入图片描述
vue-element-basesrc outermodulesfirst-child.js

// 子应用1路由菜单
import Layout from '@/layout'
import { CHILD_PREFIX } from '@/micro/config'


const appFirstRouter = {
  path: `/${CHILD_PREFIX}/first-child`,
  component: Layout,
  redirect: `/${CHILD_PREFIX}/first-child`,
  name: 'FirstChild',
  meta: {
    title: '子应用模块',
    icon: 'nested'
  },
  children: [
    {
      path: 'menu1',
      name: 'Menu1',
      meta: { title: '子应用菜单1' }
    },
    {
      path: 'menu2',
      name: 'Menu2',
      meta: { title: '子应用菜单2' }
    }
  ]
}
export default appFirstRouter

vue-element-basesrc outermodulesindex.js

// 1.导入
import appFirstRouter from './modules/first-child'

// 2.使用
appFirstRouter,

2-7、基座中配置子应用2路由

在基座中配置子应用2路由(同样vue-element-admin中有好多页面,随便找了两个配置子应用路由,只要不和子应用1重复即可)—这边的创建差不多就是把1复制过来改改
在这里插入图片描述
在这里插入图片描述
vue-element-basesrc outermodulessecond-child.js

// 子应用2路由菜单
import Layout from '@/layout'
import { CHILD_PREFIX } from '@/micro/config'


const appSecondRouter = {
  path: `/${CHILD_PREFIX}/second-child`,
  component: Layout,
  redirect: `/${CHILD_PREFIX}/second-child`,
  name: 'SecondChild',
  meta: {
    title: '子应用2模块',
    icon: 'table'
  },
  children: [
    {
      path: 'dynamic-table',
      name: 'DynamicTable',
      meta: { title: '子应用2菜单1' }
    },
    {
      path: 'drag-table',
      name: 'DragTable',
      meta: { title: '子应用2菜单2' }
    }
  ]
}
export default appSecondRouter

vue-element-basesrc outermodulesindex.js

// 1.导入
import appSecondRouter from './modules/second-child'

// 2.使用
appSecondRouter,

到此对基座的改造就结束了。

3、子应用1配置

子应用1为vue-element-first。接下来的配置都是在vue-element-first下进行的配置

3-1、修改vue.config.js

修改vue.config.js文件,设置允许跨域
在这里插入图片描述

headers: { // 设置本地运行的跨域权限
  'Access-Control-Allow-Origin': '*'
},

3-2、配置micro

和基座一样,配置micro。新建在src下新建文件夹micro。并在micro下新建index.js文件
在这里插入图片描述

// 设置 webpack 的公共路径
if (window.__MICRO_APP_ENVIRONMENT__) {
  // eslint-disable-next-line
  __webpack_public_path__ = window.__MICRO_APP_PUBLIC_PATH__ || '/'
}

3-3、修改main.js

在这里插入图片描述
main.js

// 引入 publicPath 设置
import './micro'


import Vue from 'vue'


import Cookies from 'js-cookie'


import 'normalize.css/normalize.css' // a modern alternative to CSS resets


import Element from 'element-ui'
import './styles/element-variables.scss'


import '@/styles/index.scss' // global css


import App from './App'
import store from './store'
import router from './router'


import i18n from './lang' // internationalization
import './icons' // icon
import './permission' // permission control
import './utils/error-log' // error log


import * as filters from './filters' // global filters


/**
* If you don't want to use mock-server
* you want to use MockJs for mock api
* you can execute: mockXHR()
*
* Currently MockJs will be used in the production environment,
* please remove it before going online ! ! !
*/
if (process.env.NODE_ENV === 'production') {
  const { mockXHR } = require('../mock')
  mockXHR()
}


Vue.use(Element, {
  size: Cookies.get('size') || 'medium', // set element-ui default size
  i18n: (key, value) => i18n.t(key, value)
})


// register global utility filters
Object.keys(filters).forEach(key => {
  Vue.filter(key, filters[key])
})


Vue.config.productionTip = false


// new Vue({
//   el: '#app',
//   router,
//   store,
//   i18n,
//   render: h => h(App)
// })
let app


/**
* 挂载函数
*/
function mount() {
  app = new Vue({
    el: '#app',
    router,
    store,
    i18n,
    render: function(h) { return h(App) }
  })
}


/**
* 卸载函数
*/
function unmount() {
  app.$destroy()
  app.$el.innerHTML = ''
  app = null
}


/** 微前端环境下,注册mount和unmount方法 */
if (window.__MICRO_APP_ENVIRONMENT__) { window[`micro-app-${window.__MICRO_APP_NAME__}`] = { mount, unmount } } else { mount() }

3-4、修改vue文件

在这里插入图片描述

3-5、修改路由(子应用1)

在这里插入图片描述

/** When your routing table is too long, you can split it into small modules **/


import Layout from '@/layout'


console.log(' window.__MICRO_APP_BASE_ROUTE__', window.__MICRO_APP_BASE_ROUTE__)
const nestedRouter = {
  path: window.__MICRO_APP_BASE_ROUTE__ || '/nested',
  component: Layout,
  // redirect: '/nested/menu1/menu1-1',
  name: 'Nested',
  meta: {
    title: '子应用',
    icon: 'nested'
  },
  children: [
    {
      path: 'menu1',
      component: () => import('@/views/nested/menu1/index'), // Parent router-view
      name: 'Menu1',
      meta: { title: '子应用菜单11' }
    },
    {
      path: 'menu2',
      name: 'Menu2',
      component: () => import('@/views/nested/menu2/index'),
      meta: { title: '子应用菜单22' }
    }
  ]
}


export default nestedRouter

修改完成后运行子应用1和基座,在基座中看到的子应用1效果如下图所示:

npm run dev

在这里插入图片描述

3-6、问题解决

原以为这种是路由配置有问题,但是改来改去要么404要么嵌套。不管改基座还是子应用。都没有任何效果。后面看到了一个react的文章。虽然语法等不一样,但是看到了和我上图一样的嵌套bug。
上图中子应用全部嵌套在了基座里,包含了基座已有的菜单栏及头部,所以要找到子应用的layout进行判断,如果是基座环境,则只显示主体内容。否则(即子应用)则可以全部显示。具体修改如下所示:
在这里插入图片描述
修改完成后不在有嵌套,但是在基座中点击子应用菜单,只有上方头部菜单栏变化,中间主要部分内容没有变化。要在子应用layout中对数据做一个监听。
在这里插入图片描述
micro-app-elementvue-element-firstsrclayoutindex.vue完整代码:

<template>
  <app-main v-if="inBase" />
  <div v-else :class="classObj" class="app-wrapper">
    <div v-if="device==='mobile'&&sidebar.opened" class="drawer-bg" @click="handleClickOutside" />
    <sidebar class="sidebar-container" />
    <div :class="{hasTagsView:needTagsView}" class="main-container">
      <div :class="{'fixed-header':fixedHeader}">
        <navbar />
        <tags-view v-if="needTagsView" />
      </div>
      <app-main />
      <right-panel v-if="showSettings">
        <settings />
      </right-panel>
    </div>
  </div>
</template>


<script>
import RightPanel from '@/components/RightPanel'
import { AppMain, Navbar, Settings, Sidebar, TagsView } from './components'
import ResizeMixin from './mixin/ResizeHandler'
import { mapState } from 'vuex'


export default {
  name: 'Layout',
  components: {
    AppMain,
    Navbar,
    RightPanel,
    Settings,
    Sidebar,
    TagsView
  },
  mixins: [ResizeMixin],
  computed: {
    ...mapState({
      sidebar: state => state.app.sidebar,
      device: state => state.app.device,
      showSettings: state => state.settings.showSettings,
      needTagsView: state => state.settings.tagsView,
      fixedHeader: state => state.settings.fixedHeader
    }),
    classObj() {
      return {
        hideSidebar: !this.sidebar.opened,
        openSidebar: this.sidebar.opened,
        withoutAnimation: this.sidebar.withoutAnimation,
        mobile: this.device === 'mobile'
      }
    },
    inBase() { // 判断是不是基座
      console.log('inbase microApp', window.microApp)
      console.log('inbase', window.__MICRO_APP_BASE_APPLICATION__)
      return !!window.microApp
    }
  },
  created() {
    /** 绑定数据【data属性】监听事件 */
    window.microApp && window.microApp.addDataListener(this.dataListener)
  },
  methods: {
    handleClickOutside() {
      this.$store.dispatch('app/closeSideBar', { withoutAnimation: false })
    },
    /** 监听路径,在基座中点击子应用菜单时,菜单正常切换,但主体部分内容不变 */
    dataListener(data) {
      if (data.name !== this.$route.name) {
        this.$router.push({ name: data.name })
      }
    }
  }
}
</script>


<style lang="scss" scoped>
  @import "~@/styles/mixin.scss";
  @import "~@/styles/variables.scss";


  .app-wrapper {
    @include clearfix;
    position: relative;
    height: 100%;
    width: 100%;


    &.mobile.openSidebar {
      position: fixed;
      top: 0;
    }
  }


  .drawer-bg {
    background: #000;
    opacity: 0.3;
    width: 100%;
    top: 0;
    height: 100%;
    position: absolute;
    z-index: 999;
  }


  .fixed-header {
    position: fixed;
    top: 0;
    right: 0;
    z-index: 9;
    width: calc(100% - #{$sideBarWidth});
    transition: width 0.28s;
  }


  .hideSidebar .fixed-header {
    width: calc(100% - 54px)
  }


  .mobile .fixed-header {
    width: 100%;
  }
</style>

修改完成后,micro-app在vue-element-admin中的效果就算实现了。效果图如下:
在这里插入图片描述

4、子应用2配置

子应用2配置(基本和子应用1配置一致,只需微改即可)
子应用2为vue-element-second。接下来的配置都是在vue-element- second下进行的配置。

4-1、修改vue.config.js

修改vue.config.js文件,设置允许跨域
在这里插入图片描述

headers: { // 设置本地运行的跨域权限
  'Access-Control-Allow-Origin': '*'
},

4-2、配置micro

和基座一样,配置micro。新建在src下新建文件夹micro。并在micro下新建index.js文件
在这里插入图片描述

// 设置 webpack 的公共路径
if (window.__MICRO_APP_ENVIRONMENT__) {
  // eslint-disable-next-line
  __webpack_public_path__ = window.__MICRO_APP_PUBLIC_PATH__ || '/'
}

4-3、修改main.js

在这里插入图片描述
main.js

// 引入 publicPath 设置
import './micro'
import Vue from 'vue'


import Cookies from 'js-cookie'


import 'normalize.css/normalize.css' // a modern alternative to CSS resets


import Element from 'element-ui'
import './styles/element-variables.scss'


import '@/styles/index.scss' // global css


import App from './App'
import store from './store'
import router from './router'


import i18n from './lang' // internationalization
import './icons' // icon
import './permission' // permission control
import './utils/error-log' // error log


import * as filters from './filters' // global filters


/**
* If you don't want to use mock-server
* you want to use MockJs for mock api
* you can execute: mockXHR()
*
* Currently MockJs will be used in the production environment,
* please remove it before going online ! ! !
*/
if (process.env.NODE_ENV === 'production') {
  const { mockXHR } = require('../mock')
  mockXHR()
}


Vue.use(Element, {
  size: Cookies.get('size') || 'medium', // set element-ui default size
  i18n: (key, value) => i18n.t(key, value)
})


// register global utility filters
Object.keys(filters).forEach(key => {
  Vue.filter(key, filters[key])
})


Vue.config.productionTip = false


// new Vue({
//   el: '#app',
//   router,
//   store,
//   i18n,
//   render: h => h(App)
// })
let app


/**
* 挂载函数
*/
function mount() {
  app = new Vue({
    el: '#app',
    router,
    store,
    i18n,
    render: function(h) { return h(App) }
  })
}


/**
* 卸载函数
*/
function unmount() {
  app.$destroy()
  app.$el.innerHTML = ''
  app = null
}


/** 微前端环境下,注册mount和unmount方法 */
if (window.__MICRO_APP_ENVIRONMENT__) {
  window[`micro-app-${window.__MICRO_APP_NAME__}`] = { mount, unmount }
} else {
  mount()
}

4-4、修改vue文件

在这里插入图片描述

4-5、修改路由(子应用2)

在这里插入图片描述

/** When your routing table is too long, you can split it into small modules **/


import Layout from '@/layout'


const tableRouter = {
  path: window.__MICRO_APP_BASE_ROUTE__ || '/table',
  component: Layout,
  // redirect: '/table/complex-table',
  name: 'Table',
  meta: {
    title: '子应用2',
    icon: 'table'
  },
  children: [
    {
      path: 'dynamic-table',
      component: () => import('@/views/table/dynamic-table/index'),
      name: 'DynamicTable',
      meta: { title: '子应用2菜单111' }
    },
    {
      path: 'drag-table',
      component: () => import('@/views/table/drag-table'),
      name: 'DragTable',
      meta: { title: '子应用2菜单222' }
    },
    {
      path: 'inline-edit-table',
      component: () => import('@/views/table/inline-edit-table'),
      name: 'InlineEditTable',
      meta: { title: 'inlineEditTable' }
    },
    {
      path: 'complex-table',
      component: () => import('@/views/table/complex-table'),
      name: 'ComplexTable',
      meta: { title: 'complexTable' }
    }
  ]
}
export default tableRouter

接下来浏览器效果和搭建子应用1时一样,是嵌套的,如下:
在这里插入图片描述

4-6、问题解决

需要对子应用的layout进行判断,如果是基座环境,则只显示主体内容。否则(即子应用)则可以全部显示。至于为什么修改,看子应用1即可,不多说了具体修改如下所示:
在这里插入图片描述
micro-app-elementvue-element-secondsrclayoutindex.vue完整代码:

<template>
  <app-main v-if="inBase" />
  <div v-else :class="classObj" class="app-wrapper">
    <div v-if="device==='mobile'&&sidebar.opened" class="drawer-bg" @click="handleClickOutside" />
    <sidebar class="sidebar-container" />
    <div :class="{hasTagsView:needTagsView}" class="main-container">
      <div :class="{'fixed-header':fixedHeader}">
        <navbar />
        <tags-view v-if="needTagsView" />
      </div>
      <app-main />
      <right-panel v-if="showSettings">
        <settings />
      </right-panel>
    </div>
  </div>
</template>


<script>
import RightPanel from '@/components/RightPanel'
import { AppMain, Navbar, Settings, Sidebar, TagsView } from './components'
import ResizeMixin from './mixin/ResizeHandler'
import { mapState } from 'vuex'


export default {
  name: 'Layout',
  components: {
    AppMain,
    Navbar,
    RightPanel,
    Settings,
    Sidebar,
    TagsView
  },
  mixins: [ResizeMixin],
  computed: {
    ...mapState({
      sidebar: state => state.app.sidebar,
      device: state => state.app.device,
      showSettings: state => state.settings.showSettings,
      needTagsView: state => state.settings.tagsView,
      fixedHeader: state => state.settings.fixedHeader
    }),
    classObj() {
      return {
        hideSidebar: !this.sidebar.opened,
        openSidebar: this.sidebar.opened,
        withoutAnimation: this.sidebar.withoutAnimation,
        mobile: this.device === 'mobile'
      }
    },
    inBase() { // 判断是不是基座
      // console.log('inbase microApp', window.microApp)
      // console.log('inbase', window.__MICRO_APP_BASE_APPLICATION__)
      return !!window.microApp
    }
  },
  created() {
    /** 绑定数据【data属性】监听事件 */
    window.microApp && window.microApp.addDataListener(this.dataListener)
  },
  methods: {
    handleClickOutside() {
      this.$store.dispatch('app/closeSideBar', { withoutAnimation: false })
    },
    /** 监听路径,在基座中点击子应用菜单时,菜单正常切换,但主体部分内容不变 */
    dataListener(data) {
      if (data.name !== this.$route.name) {
        this.$router.push({ name: data.name })
      }
    }
  }
}
</script>


<style lang="scss" scoped>
  @import "~@/styles/mixin.scss";
  @import "~@/styles/variables.scss";


  .app-wrapper {
    @include clearfix;
    position: relative;
    height: 100%;
    width: 100%;


    &.mobile.openSidebar {
      position: fixed;
      top: 0;
    }
  }


  .drawer-bg {
    background: #000;
    opacity: 0.3;
    width: 100%;
    top: 0;
    height: 100%;
    position: absolute;
    z-index: 999;
  }


  .fixed-header {
    position: fixed;
    top: 0;
    right: 0;
    z-index: 9;
    width: calc(100% - #{$sideBarWidth});
    transition: width 0.28s;
  }


  .hideSidebar .fixed-header {
    width: calc(100% - 54px)
  }


  .mobile .fixed-header {
    width: 100%;
  }
</style>

修改完成后,浏览器实现效果图如下:
在这里插入图片描述
到此对于micro-app在vue-element-admin中的使用就介绍完了。

5、打包

关于打包vue-element-admin貌似已经配置好了,直接打包即可

npm run build:prod

打包结果又是这样的,跟之前一样报错:
在这里插入图片描述
本地运行不起来,按照网上找的方法修改都没用。所以后面直接部署了,部署下来没有问题。所以打包这边注意以下两点就好了。

1、vue.config.js中的publicPath要修改。基座和子应用都要修改。如下图所示:
在这里插入图片描述

2、修改router/index.js。基座和子应用都要修改。修改路由方式。如下图所示:
在这里插入图片描述
打包结束后对应基座和子应用下都会生成对应的dist文件夹,如下图所示。单独打包单独部署就是基座和子应用都要打包。
在这里插入图片描述

6、部署

使用nginx部署,之前已经研究过了,部署这边就很快。如果不懂可参考部署相关内容

6-1、dist放置

将打包好的dist文件分别放入对应好的文件夹中,当然不一定像我这样,只要后期目录地址写对即可
在这里插入图片描述

6-2、配置

主要是对nginx.conf的配置
在这里插入图片描述
主要配置代码:

server {
        listen       9527;
        server_name  localhost;
        #charset koi8-r;
        #access_log  logs/host.access.log  main;
        location / {
            root base/dist;
            add_header Access-Control-Allow-Origin *;
            if ( $request_uri ~* ^.+.(js|css|jpg|png|gif|tif|dpg|jpeg|eot|svg|ttf|woff|json|mp4|rmvb|rm|wmv|avi|3gp)$ ){
              add_header Cache-Control max-age=7776000;
              add_header Access-Control-Allow-Origin *;
            }
            try_files $uri $uri/ /index.html;
        }   
    }


    server {
        listen       9528;
        server_name  localhost;
        location / {
            root first-child/dist;
            add_header Access-Control-Allow-Origin *;
            if ( $request_uri ~* ^.+.(js|css|jpg|png|gif|tif|dpg|jpeg|eot|svg|ttf|woff|json|mp4|rmvb|rm|wmv|avi|3gp)$ ){
              add_header Cache-Control max-age=7776000;
              add_header Access-Control-Allow-Origin *;
            }
            try_files $uri $uri/ /index.html;
        }
     }
     
     server {
        listen       9529;
        server_name  localhost;
        location / {
            root second-child/dist;
            add_header Access-Control-Allow-Origin *;
            if ( $request_uri ~* ^.+.(js|css|jpg|png|gif|tif|dpg|jpeg|eot|svg|ttf|woff|json|mp4|rmvb|rm|wmv|avi|3gp)$ ){
              add_header Cache-Control max-age=7776000;
              add_header Access-Control-Allow-Origin *;
            }
            try_files $uri $uri/ /index.html;
        }
     }

6-3、浏览器地址

部署完之后可以在浏览器中输入:

http://127.0.0.1:9527/      // 基座地址
http://127.0.0.1:9528/    // 子应用1地址
http://127.0.0.1:9529/    // 子应用2地址

6-4、部署效果

部署后浏览器显示效果:
在这里插入图片描述

总结

到此micro-app在vue-element-admin中的使用框架就算搭完了,关于micro-app在vue-element-admin中的其他使用,还需后续在研究。

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。