The sample code can be downloaded here. The construction process is as follows

Project creation

The project is created by vUE’s official scaffolding, base project and subprojects app_first and app_second

vue create base

vue create app_first
vue create app_second
Copy the code

Base item modification

Add the local run configuration file vue.config.js

module.exports = {
    devServer: {
        host: 'localhost'
        , port: 3000}}Copy the code

Install the Micro-app plug-in

npm install @micro-zoe/micro-app --save
Copy the code

Add the micro/index.js file

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

/ / enable micro
microApp.start({
    preFetchApps: config.MICRO_APPS // Load the subproject
    , globalAssets: config.GLOBAL_ASSETS // Load global resources
})
Copy the code

Add the micro/config.js file

// Subapplication prefix
export const CHILD_PREFIX = 'app'

// Address of the child application
export const MICRO_APPS = [
    { name: 'first-child'.url: `http://localhost:3001/`}, {name: 'second-child'.url: `http://localhost:3002/`}]// Global resources
export const GLOBAL_ASSETS = {
    js: [].css: []}Copy the code

Modify the entry file main.js to introduce micro-app configuration

import './micro'.Copy the code

Modify the app. vue file

<template> <div> <! -- Routing links -->... </div> <div> <micro-app v-if="isChild" v-bind="micro" destory @datachange='handleDataChange'></micro-app> <router-view v-else></router-view> </div> </template> <script> import { MICRO_APPS, CHILD_PREFIX } from './micro/config.js' export default { ... , data(){ return { ... , isChild: false // Whether it is a submodule, micro: {url: "// subapplication address, excluding routing address, key:" // The key value of the Vue tag, used when switching between different submodules, component rendering, name: "// submodule name, unique value, data: {} // data that needs to be passed into the submodule, baseroute:" // submodule routing address}}}, watch: ChangeChild (val)}}, created () {this.changechild (val.$route)}, methods: {... , getAppUrl (name) {/ / access module the url and name return MICRO_APPS. Find (= > app. The app name = = = name) | | {}}, ChangeChild (route) {let path = route.path.tolowerCase (), paths = path.split('/') // Check whether it is a submodule, IsChild = paths.length > 2 && paths[1] === CHILD_PREFIX if (this.isChild) {let app = this.getAppUrl(paths[2]) this.micro = { ... ${app.name} ', baseroute: ${app.name} ' `/${CHILD_PREFIX}/${paths[2]}` } } } , HandleDataChange (event) {let data = event.detail.data if(data.route) this.$router.push({name: data.route.name }) } } } </script>Copy the code

Example Modify the routing file router/index.js

.import { CHILD_PREFIX } from '@/micro/config.js'

const routes = [
    ...
    , { // App_first project route
        path: ` /${CHILD_PREFIX}/first-child`
	, name: 'FirstChild'
	, children: [{path: 'home'
                , name: 'FirstHome'}, {path: 'about'
                , name: 'FirstAbout'}]}, {// app_second project route
	path: ` /${CHILD_PREFIX}/second-child`
	, name: 'SecondChild'
	, children: [{path: 'home'
                , name: 'SecondHome'}, {path: 'about'
                , name: 'SecondAbout'}]}]...Copy the code

Subproject modification

Add the local run configuration file vue.config.js to allow cross-domain access

module.exports = {
    devServer: {
        host: 'localhost'
        , port: 3001
        , headers: { // Set cross-domain permissions to run locally
            'Access-Control-Allow-Origin': The '*',}}}Copy the code

Add the micro/index.js file

// Set the public path for webpack
__webpack_public_path__ = window.__MICRO_APP_PUBLIC_PATH__ || '/'
Copy the code

Modify the entry file mian. Js

import './micro'.let app

/** ** mount function */
function mount () {
    app = new Vue({
        el: '#app'
        , router
        , render: function (h) { return h(App) }
    })
}

/** * unload function */
function unmount () {
    app.$destroy()
    app.$el.innerHTML = ' '
    app = null
}

// Register the mount and unmount methods in the micro-front-end environment
if (window.__MICRO_APP_ENVIRONMENT__)
    window[`micro-app-The ${window.__MICRO_APP_NAME__}`] = { mount, unmount }
else
    mount()
Copy the code

Modify the app. vue file

<template> <div id="app"> <div id="nav"> <router-link :to="`${prefix}/home`">Home</router-link> | <router-link :to="`${prefix}/about`">About</router-link> | <button @click="goto('SecondHome')">SecondHome</button> | <button @click="goto('SecondAbout')">SecondAbout</button> </div> <router-view /> </div> </template> <script> export default { . , methods: { ... , dataListener (data) {// There is an exception if (data.name! == this.$route.name) this.$router.push({ name: Data.name})}, goto (name) {// Send data to base project window.microapp.dispatch ({route: { name } }) } } , Created () {/ / bind data monitoring data property 】 【 event window. The microApp && window. MicroApp. AddDataListener (enclosing dataListener)}, Destroyed () {/ / removing data monitoring data property 】 【 event window. The microApp && window. MicroApp. RemoveDataListener (enclosing dataListener)}} </script>Copy the code

Example Modify the routing file router/index.js

.const routes = [
    {
        path: window.__MICRO_APP_BASE_ROUTE__ || '/' // Set the path prefix depending on the environment in which the project is running
        , name: 'Home'
        , redirect: { name: 'FirstHome'},component: () = > import('.. /views/Empty.vue') // empty. vue is a page containing only router-view for rendering children
        , children: [...]. }]...Copy the code

Project start

Enter the project folder respectively, run NPM run serve under CMD, start the project, visit localhost:3000 to view the complete project, or open localhost:3001 or localhost:3002 to access a single sub-project

Some problem solving

  • Common module code

    You can create a separate repository of common code and introduce it as submodules in each project

  • Nginx deployment

    When the micro front end is deployed to multiple addresses, it can use nginx reverse proxy to proxy the sub-project address to the main project address, so that the main project and sub-project can use the same storage

server { listen 3000; server_name localhost; location / { root D:/base/dist/; index index.html index.htm; try_files $uri $uri/ /index.html; } # delegate subproject location /first_child/ {proxy_pass http://localhost:3001/; }}  
#Subproject access portserver { listen 3001; server_name localhost; Add_header access-control-allow-origin *; location / { root D:/first_child/dist/; index index.html index.htm; try_files $uri $uri/ /index.html; }}Copy the code

MicroApp Sample building [Vue]