Note: The parent application and the main application in this article are only named differently, but both refer to the main application base.

I came to this thinking after reading an article based on the best Practices of Qiankun micro front-end (illustrated) – Inter-application Communication, which introduced the use of Shared communication

// micro-app-vue/src/main.js
/ /...

/** * Render functions * run in the main application lifecycle hook/run when the child application starts alone */
function render(props = {}) {
  // If the shared passed in is empty, use the child's own shared
  // If the shared passed in is not empty, the shared passed in by the main application overloads the shared of the child application
  const { shared = SharedModule.getShared() } = props;
  SharedModule.overloadShared(shared);

  router = new VueRouter({
    base: window.__POWERED_BY_QIANKUN__ ? "/vue" : "/".mode: "history",
    routes,
  });

  // Mount the application
  instance = new Vue({
    router,
    render: (h) = > h(App),
  }).$mount("#app");
}
Copy the code

Const {shared = sharedmodule.getshared ()} = props is useful for structuring assignments to specify default values for parent and child applications sharing a shared object, In Vue we usually use Vuex for data set state processing. What if I just pass the store created by Vuex from the parent app to the child app?

Pass the parent app Store directly to the child app

The code can be found at github.com/fxss5201/mi… Main branch and github.com/fxss5201/mi… The main branches:

The parent application:

scr/micro/apps.ts

import store from '@/store'

const apps = [
  /** * name: micro app name - Unique * entry: micro app entry - Load the micro app through this address * container: mount the micro app to the node - After the micro app is loaded, it will be mounted to the node * activeRule: Routing rules triggered by the micro-application - The micro-application will be loaded after the routing rule is triggered
  {
    name: 'VueMicroApp'.entry: '//localhost:8111'.container: '#frame'.activeRule: '/vue'.props: {
      // Here we pass the parent app's store to the child app
      store
    }
  }
]

export default apps
Copy the code

The store is created in the parent app via Vuex:

src/store/index.ts

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    token: 'store123456'
  },
  mutations: {
    setToken (state, val) {
      state.token = val
    }
  },
  actions: {},modules: {}})Copy the code

Then you need to do the reception processing in the child application.

Son:

src/main.js

import './public-path'
import Vue from 'vue'
import VueRouter from 'vue-router'
import App from './App.vue'
import routes from './router'
import microStore from './store'
import actions from '@/shared/actions'
import './plugins/element.js'

Vue.config.productionTip = false

let router = null
let instance = null
function render (props = {}) {
  console.log('micro-app-test-vue')
  console.log(props)
  // The store created by the parent application is passed in by destructing the assignment
  const { container, store = microStore } = props

  if (props) {
    // Inject an Actions instance
    actions.setActions(props)
  }

  router = new VueRouter({
    base: window.__POWERED_BY_QIANKUN__ ? '/vue/' : '/'.mode: 'history',
    routes
  })

  instance = new Vue({
    router,
    store,
    render: (h) = > h(App)
  }).$mount(container ? container.querySelector('#app') : '#app')}// Independent runtime
if (!window.__POWERED_BY_QIANKUN__) {
  render()
}

export async function bootstrap () {
  console.log('[vue] vue app bootstraped')}export async function mount (props) {
  console.log('[vue] props from main framework', props)
  render(props)
}
export async function unmount () {
  instance.$destroy()
  instance.$el.innerHTML = ' '
  instance = null
  router = null
}
Copy the code

There are four menus in the parent app, as follows:

  menus: [
    {
      key: 'Home'.title: 'Main App - Home Page'.icon: 'el-icon-location'.path: '/'
    },
    {
      key: 'About'.title: 'Main Application - About'.icon: 'el-icon-location'.path: '/about'
    },
    {
      key: 'VueMicroAppHome'.title: 'Vue Sub-application - Home Page '.icon: 'el-icon-menu'.path: '/vue/'
    },
    {
      key: 'VueMicroAppAbout'.title: 'Vue Sub-Application - About '.icon: 'el-icon-menu'.path: '/vue/about'}]Copy the code

Click the button to switch values.

Parent App app. vue file:

<template>
  <div>
    <el-container>
      <el-aside width="200px">
        <main-menu :menus="menus"></main-menu>
      </el-aside>
      <el-container>
        <el-header>
          <div>Header</div>
          <div class="head-content">
            <span>Main application Action communication:</span>
            <el-divider direction="vertical"></el-divider>
            <span>actionToken: {{ actionToken }}</span>
            <el-divider direction="vertical"></el-divider>
            <el-button size="mini" @click="setMainAtionToken">Set actionToken to mainAtionToken</el-button>
          </div>
          <div class="head-content">
            <span>Main application Props(VUEX) Communication:</span>
            <el-divider direction="vertical"></el-divider>
            <span>vuexToken: {{ vuexToken }}</span>
            <el-divider direction="vertical"></el-divider>
            <el-button size="mini" @click="setMainVuexToken">Example Set vuexToken to mainVuexToken</el-button>
          </div>
        </el-header>
        <el-main>
          <! -- Main application rendering area, used to mount components triggered by main application routing -->
          <router-view v-show="$route.name" />

          <! -- Child application rendering area, used to mount child application nodes -->
          <section v-show=! "" $route.name" id="frame"></section>
        </el-main>
        <el-footer>Footer</el-footer>
      </el-container>
    </el-container>
  </div>
</template>

<script lang="ts">
import { Component, Vue, Watch } from 'vue-property-decorator'
import MainMenu from '@/components/MainMenu.vue'
import actions from '@/shared/actions'

@Component({
  components: {
    MainMenu
  }
})

export default class App extends Vue {
  /** * menu list * key: unique key value * title: menu title * icon? : icon * path: path of the menu */
  menus = [
    {
      key: 'Home'.title: 'Main App - Home Page'.icon: 'el-icon-location'.path: '/'
    },
    {
      key: 'About'.title: 'Main Application - About'.icon: 'el-icon-location'.path: '/about'
    },
    {
      key: 'VueMicroAppHome'.title: 'Vue Sub-application - Home Page '.icon: 'el-icon-menu'.path: '/vue/'
    },
    {
      key: 'VueMicroAppAbout'.title: 'Vue Sub-Application - About '.icon: 'el-icon-menu'.path: '/vue/about'}]// Use the Action communication Token
  actionToken = ' '

  get vuexToken (): string {
    return this.$store.state.token
  }

  mounted (): void {
    console.log(this.menus)

    actions.onGlobalStateChange((state, prevState) = > {
      // state: state after the change; PrevState: indicates the status before the change
      console.log('Master app Observer: Token value before change', prevState.token)
      console.log('Master Application Observer: Changed token value is', state.token)
      this.actionToken = state.token
    }, true)
  }

  setMainAtionToken (): void {
    actions.setGlobalState({ token: 'mainAtionToken' })
  }

  setMainVuexToken (): void {
    this.$store.commit('setToken'.'mainVuexToken')
  }

  @Watch('vuexToken', { immediate: true })
  onVuexTokenChange (val: string, oldVal: string): void {
    // Vuex token value: val changed state; OldVal: indicates the status before the change
    console.log('The token value before the change in the main application vuex is', oldVal)
    console.log('The token value changed in the main application vuex is', val)
  }
}
</script>
Copy the code

App.vue file for the child App:

<template>
  <div id="app-box">
    <div>
      <div class="content">
        <span>Child application Action communication:</span>
        <el-divider direction="vertical"></el-divider>
        <span>actionToken: {{ actionToken }}</span>
        <el-divider direction="vertical"></el-divider>
        <el-button size="mini" @click="setMicroActionToken">Set actionToken to microActionToken</el-button>
      </div>
      <div class="content">
        <span>Sub-application Props(VUEX) Communication:</span>
        <el-divider direction="vertical"></el-divider>
        <span>vuexToken: {{ vuexToken }}</span>
        <el-divider direction="vertical"></el-divider>
        <el-button size="mini" @click="setMicroVuexToken">Example Set the vuexToken to microVuexToken</el-button>
      </div>
      <router-link to="/">Home</router-link> |
      <router-link to="/about">About</router-link>
    </div>
    <router-view/>
  </div>
</template>

<script>
import actions from '@/shared/actions'
export default {
  name: 'app',
  data () {
    return {
      actionToken: ' '.vuexToken: ' '
    }
  },
  mounted () {
    /** Because in main.js const {container, store = microStore} = props Store In this case, the Store of the main application was not dynamic in the sub-applications, so only the initialization assignment and the mutation subscription of the main application Store were required to modify the current data. In order to unify the processing, the mode of modifying the current data by the initialization assignment and the mutation subscription of the main application Store was required */
    // initialize to get the value
    this.vuexToken = this.$store.state.token

    console.log(this.$store)
    console.log('window.__POWERED_BY_QIANKUN__'.window.__POWERED_BY_QIANKUN__)
    if (window.__POWERED_BY_QIANKUN__) {
      actions.onGlobalStateChange((state, prevState) = > {
        // state: state after the change; PrevState: indicates the status before the change
        console.log('Child app Observer: Token value before change', prevState.token)
        console.log('Child application observer: changed token value is', state.token)

        const { token } = state
        this.actionToken = token
      }, true)}// Subscribe to store mutation
    this.$store.subscribe((mutation, state) = > {
      console.log(mutation.type)
      console.log(mutation.payload)
      console.log(state)
      console.log(this.$store)
      this.vuexToken = state.token
    })
  },
  methods: {
    setMicroActionToken () {
      if (window.__POWERED_BY_QIANKUN__) {
        actions.setGlobalState({ token: 'microActionToken' })
      }
    },

    setMicroVuexToken () {
      this.$store.commit('setToken'.'microVuexToken')}},watch: {
    vuexToken (val, oldVal) {
      console.log('The token value before the change in vuex in the child application is', oldVal)
      console.log('The token value changed in the child application vuex is', val)
    }
  }
}
</script>
Copy the code

Both parent and child applications have the corresponding button clicking event to switch state value. Also, the official communication mode of The Qiankun is action communication and the communication mode of the props communication to the store created by Vuex, which has some problems. Use (Vuex) and new in the parent application, so the store cannot use computed attributes in the child application. There is also a corresponding interpretation in the app. vue file of the child App, temporarily modifying the current data by initialization assignment and subscriing to mutation in the main App store. This allows for communication, but it’s still a bit of a hassle, and it’s not clear what other pits you’ll run into if you use the main app store in a child app, so here’s what to think about.

eventBuscommunication

The code can be found at github.com/fxss5201/mi… Bus branch or github.com/fxss5201/mi… Bus branch and github.com/fxss5201/mi… Bus branches:

Why a new project, github.com/fxss5201/mi… The main application dock uses TypeScript, while the child application dock uses JavaScript. As a result, some files are not easy to copy directly, so we created github.com/fxss5201/mi… The project is also in JavaScript, but you can always use TypeScript, so I’m just demonstrating.

The following to github.com/fxss5201/mi… Bus branch and github.com/fxss5201/mi… The bus branch, which uses JavaScript, is available at github.com/fxss5201/mi… The project, the idea is the same.

The parent application:

SRC/plugins/bus. Create eventBus js

import Vue from 'vue'
import store from '. /.. /store'

// Use Event Bus
const bus = new Vue({
  data: {
    // Keep initialization consistent with store data
    // The basic type can be used in this way, and the reference type can be used in cloneDeep copy
    // https://www.lodashjs.com/docs/lodash.cloneDeep#_clonedeepvalue
    token: store.state.tokenModule.token
  }
})

export default bus
Copy the code

SRC /plugins/ buson.js where the $on of eventBus is uniformly placed

export default {
  install (thisArg) {
    thisArg.$bus.$on('setBusToken'.(val) = > {
      thisArg.$bus.token = val
      thisArg.$store.commit('tokenModule/setToken', val)
    })
  }
}
Copy the code

src/micro/apps.js

import bus from '. /.. /plugins/bus'

const apps = [
  /** * name: micro app name - Unique * entry: micro app entry - Load the micro app through this address * container: mount the micro app to the node - After the micro app is loaded, it will be mounted to the node * activeRule: Routing rules triggered by the micro-application - The micro-application will be loaded after the routing rule is triggered
  {
    name: 'VueMicroApp'.entry: '//localhost:8111'.container: '#frame'.activeRule: '/vue'.props: {
      bus
    }
  }
]

export default apps
Copy the code

src/main.js

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import './plugins/element.js'
import startQiankun from './micro'
import bus from './plugins/bus'

startQiankun({ prefetch: false })
Vue.config.productionTip = false
// Mount bus to Vue prototype to keep parent-child application consistent
Vue.prototype.$bus = bus

new Vue({
  router,
  store,
  render: h= > h(App)
}).$mount('#app')
Copy the code

And put the data that communicates between the parent app and the parent app into a separate Vuex module, so the parent app store becomes the following:

src/store/index.js

import Vue from 'vue'
import Vuex from 'vuex'
import tokenModule from './tokenModule'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {},mutations: {},actions: {},modules: {
    tokenModule
  }
})
Copy the code

src/store/tokenModule.js

export default {
  namespaced: true.state: {
    token: 'store123456'
  },
  mutations: {
    setToken (state, val) {
      console.log('main', val)
      state.token = val
    }
  },
  actions: {},modules: {}}Copy the code

After that, the parent App app.vue was modified:

<template>
  <div>
    <el-container>
      <el-aside width="200px">
        <main-menu :menus="menus"></main-menu>
      </el-aside>
      <el-container>
        <el-header>
          <div>Header</div>
          <div class="head-content">
            <span>Main application Action communication:</span>
            <el-divider direction="vertical"></el-divider>
            <span>actionToken: {{ actionToken }}</span>
            <el-divider direction="vertical"></el-divider>
            <el-button size="mini" @click="setMainAtionToken">Set actionToken to mainAtionToken</el-button>
          </div>
          <div class="head-content">
            <span>Main application Props(BUS) Communication:</span>
            <el-divider direction="vertical"></el-divider>
            <span>busToken: {{ busToken }}</span>
            <el-divider direction="vertical"></el-divider>
            <el-button size="mini" @click="setMainBusToken">Set busToken to mainBusToken</el-button>
          </div>
        </el-header>
        <el-main>
          <! -- Main application rendering area, used to mount components triggered by main application routing -->
          <router-view v-show="$route.name" />

          <! -- Child application rendering area, used to mount child application nodes -->
          <section v-show=! "" $route.name" id="frame"></section>
        </el-main>
        <el-footer>Footer</el-footer>
      </el-container>
    </el-container>
  </div>
</template>

<script>
import MainMenu from '@/components/MainMenu.vue'
import actions from '@/shared/actions'
import busOn from './plugins/busOn'

export default {
  name: 'app'.components: {
    MainMenu
  },
  data () {
    return {
      menus: [{key: 'Home'.title: 'Main App - Home Page'.icon: 'el-icon-location'.path: '/'
        },
        {
          key: 'About'.title: 'Main Application - About'.icon: 'el-icon-location'.path: '/about'
        },
        {
          key: 'VueMicroAppHome'.title: 'Vue Sub-application - Home Page '.icon: 'el-icon-menu'.path: '/vue/'
        },
        {
          key: 'VueMicroAppAbout'.title: 'Vue Sub-Application - About '.icon: 'el-icon-menu'.path: '/vue/about'}].actionToken: ' '}},computed: {
    busToken () {
      return this.$store.state.tokenModule.token
    }
  },
  mounted () {
    actions.onGlobalStateChange((state, prevState) = > {
      // state: state after the change; PrevState: indicates the status before the change
      console.log('Master app Observer: Token value before change', prevState.token)
      console.log('Master Application Observer: Changed token value is', state.token)
      this.actionToken = state.token
    }, true)

    // bus.$on('setBusToken', (val: string) => {
    // this.$store.commit('tokenModule/setToken', val)
    // })

    // Multiple eventBus unified writing place
    busOn.install(this)},methods: {
    setMainAtionToken () {
      actions.setGlobalState({ token: 'mainAtionToken' })
    },
    setMainBusToken () {
      // To prevent multiple commit setToken, place the commit setToken in eventBus and emit only eventBus
      // this.$store.commit('tokenModule/setToken', 'mainBusToken')
      this.$bus.$emit('setBusToken'.'mainBusToken')}},watch: {
    busToken: {
      immediate: true,
      handler (val, oldVal) {
        // Vuex token value: val changed state; OldVal: indicates the status before the change
        console.log('The token value before the change in the main application vuex is', oldVal)
        console.log('The token value changed in the main application vuex is', val)
      }
    }
  }
}
</script>
Copy the code

Next, let’s talk about the changes to the sub-apps. Sub-apps:

SRC /plugins/ buson.js, SRC /plugins/ buson.js, SRC /store/ tokenmodule.js, SRC /store/tokenModule. It’s easy to copy and paste between parent and child apps, so parent and child apps are either all iN JavaScript or typeScript.

src/main.js

import './public-path'
import Vue from 'vue'
import VueRouter from 'vue-router'
import App from './App.vue'
import routes from './router'
import store from './store'
import actions from '@/shared/actions'
import './plugins/element.js'
import microBus from './plugins/bus'

Vue.config.productionTip = false

let router = null
let instance = null
function render (props = {}) {
  console.log('micro-app-test-vue')
  console.log(props)
  // The parent application applies the bus of the parent application when it passes bus, and the child application applies the bus of the child application when it does not pass bus
  const { container, bus = microBus } = props
  Vue.prototype.$bus = bus

  if (props) {
    // Inject an Actions instance
    actions.setActions(props)
  }

  router = new VueRouter({
    base: window.__POWERED_BY_QIANKUN__ ? '/vue/' : '/'.mode: 'history',
    routes
  })

  instance = new Vue({
    router,
    store,
    render: (h) = > h(App)
  }).$mount(container ? container.querySelector('#app') : '#app')}// Independent runtime
if (!window.__POWERED_BY_QIANKUN__) {
  render()
}

export async function bootstrap () {
  console.log('[vue] vue app bootstraped')}export async function mount (props) {
  console.log('[vue] props from main framework', props)
  render(props)
}
export async function unmount () {
  instance.$destroy()
  instance.$el.innerHTML = ' '
  instance = null
  router = null
}
Copy the code

src/App.vue

<template>
  <div id="app-box">
    <div>
      <div class="content">
        <span>Child application Action communication:</span>
        <el-divider direction="vertical"></el-divider>
        <span>actionToken: {{ actionToken }}</span>
        <el-divider direction="vertical"></el-divider>
        <el-button size="mini" @click="setMicroActionToken">Set actionToken to microActionToken</el-button>
      </div>
      <div class="content">
        <span>Subapplication Props(BUS) Communication:</span>
        <el-divider direction="vertical"></el-divider>
        <span>busToken: {{ busToken }}</span>
        <el-divider direction="vertical"></el-divider>
        <el-button size="mini" @click="setMicroBusToken">Set busToken to microBusToken</el-button>
      </div>
      <router-link to="/">Home</router-link> |
      <router-link to="/about">About</router-link>
    </div>
    <router-view/>
  </div>
</template>

<script>
import actions from '@/shared/actions'
import busOn from './plugins/busOn'

export default {
  name: 'app',
  data () {
    return {
      actionToken: ' '}},computed: {
    busToken () {
      return this.$store.state.tokenModule.token
    }
  },
  mounted () {
    console.log('window.__POWERED_BY_QIANKUN__'.window.__POWERED_BY_QIANKUN__)
    if (window.__POWERED_BY_QIANKUN__) {
      actions.onGlobalStateChange((state, prevState) = > {
        // state: state after the change; PrevState: indicates the status before the change
        console.log('Child app Observer: Token value before change', prevState.token)
        console.log('Child application observer: changed token value is', state.token)

        const { token } = state
        this.actionToken = token
      }, true)}// Multiple eventBus unified writing place
    busOn.install(this)
    if (window.__POWERED_BY_QIANKUN__) {
      // The embedded parent app initializes the data when entering the page
      this.$bus.$emit('setBusToken'.this.$bus.token)
    }
  },
  methods: {
    setMicroActionToken () {
      if (window.__POWERED_BY_QIANKUN__) {
        actions.setGlobalState({ token: 'microActionToken' })
      }
    },

    setMicroBusToken () {
      // To prevent multiple commit setToken, place the commit setToken in eventBus and emit only eventBus
      // this.$store.commit('tokenModule/setToken', 'microBusToken')
      this.$bus.$emit('setBusToken'.'microBusToken')}},watch: {
    busToken (val, oldVal) {
      console.log('The token value before the change in vuex in the child application is', oldVal)
      console.log('The token value changed in the child application vuex is', val)
    }
  }
}
</script>
Copy the code

This communication mode mainly uses the $emit trigger event and $ON listening event of eventBus. If the child application is used alone, the child application’s eventBus is used to change the value in store. If the child application is embedded in the parent application, the parent application’s eventBus is used. The advantage of this scheme is that there is no need to do any adaptation when the child application is embedded into the parent application and used alone.

action + Vuexcommunication

The code can be found at github.com/fxss5201/mi… The Action-vuex branch (github.com/fxss5201/mi… Action-vuex branch) and github.com/fxss5201/mi… The action – vuex branch:

Action + Vuex communication mainly uses the official action to communicate, and then updates the value to the Vuex:

Main application:

src/App.vue

<template>
  <div>
    <el-container>
      <el-aside width="200px">
        <main-menu :menus="menus"></main-menu>
      </el-aside>
      <el-container>
        <el-header>
          <div>Header</div>
          <div class="head-content">
            <span>Main application Action communication:</span>
            <el-divider direction="vertical"></el-divider>
            <span>actionToken: {{ actionToken }}</span>
            <el-divider direction="vertical"></el-divider>
            <el-button size="mini" @click="setMainAtionToken">Set actionToken to mainAtionToken</el-button>
          </div>
          <div class="head-content">
            <span>Main application Action + Vuex communication:</span>
            <el-divider direction="vertical"></el-divider>
            <span>actionVuexToken: {{ actionVuexToken }}</span>
            <el-divider direction="vertical"></el-divider>
            <el-button size="mini" @click="setMainActionVuexToken">Set actionVuexToken to mainActionVuexToken</el-button>
          </div>
        </el-header>
        <el-main>
          <! -- Main application rendering area, used to mount components triggered by main application routing -->
          <router-view v-show="$route.name" />

          <! -- Child application rendering area, used to mount child application nodes -->
          <section v-show=! "" $route.name" id="frame"></section>
        </el-main>
        <el-footer>Footer</el-footer>
      </el-container>
    </el-container>
  </div>
</template>

<script>
import MainMenu from '@/components/MainMenu.vue'
import actions from '@/shared/actions'

export default {
  name: 'app'.components: {
    MainMenu
  },
  data () {
    return {
      menus: [{key: 'Home'.title: 'Main App - Home Page'.icon: 'el-icon-location'.path: '/'
        },
        {
          key: 'About'.title: 'Main Application - About'.icon: 'el-icon-location'.path: '/about'
        },
        {
          key: 'VueMicroAppHome'.title: 'Vue Sub-application - Home Page '.icon: 'el-icon-menu'.path: '/vue/'
        },
        {
          key: 'VueMicroAppAbout'.title: 'Vue Sub-Application - About '.icon: 'el-icon-menu'.path: '/vue/about'}].actionToken: ' '}},computed: {
    actionVuexToken () {
      return this.$store.state.tokenModule.token
    }
  },
  mounted () {
    actions.onGlobalStateChange((state, prevState) = > {
      // state: state after the change; PrevState: indicates the status before the change
      console.log('Master app Observer: Token value before change', prevState.token)
      console.log('Master Application Observer: Changed token value is', state.token)

      this.actionToken = state.token
      this.$store.commit('tokenModule/setToken', state.token)
    }, true)},methods: {
    setMainAtionToken () {
      actions.setGlobalState({ token: 'mainAtionToken' })
    },
    setMainActionVuexToken () {
      // Note that actions are used to change this. Commit in onGlobalStateChange
      actions.setGlobalState({ token: 'mainActionVuexToken'})}},watch: {
    actionVuexToken: {
      immediate: true,
      handler (val, oldVal) {
        // Vuex token value: val changed state; OldVal: indicates the status before the change
        console.log('The token value before the change in the main application vuex is', oldVal)
        console.log('The token value changed in the main application vuex is', val)
      }
    }
  }
}
</script>
Copy the code

Son:

src/App.vue

<template>
  <div id="app-box">
    <div>
      <div class="content">
        <span>Child application Action communication:</span>
        <el-divider direction="vertical"></el-divider>
        <span>actionToken: {{ actionToken }}</span>
        <el-divider direction="vertical"></el-divider>
        <el-button size="mini" @click="setMicroActionToken">Set actionToken to microActionToken</el-button>
      </div>
      <div class="content">
        <span>Sub-application Action + Vuex communication:</span>
        <el-divider direction="vertical"></el-divider>
        <span>actionVuexToken: {{ actionVuexToken }}</span>
        <el-divider direction="vertical"></el-divider>
        <el-button size="mini" @click="setMicroActionVuexToken">Set actionVuexToken to microActionVuexToken</el-button>
      </div>
      <router-link to="/">Home</router-link> |
      <router-link to="/about">About</router-link>
    </div>
    <router-view/>
  </div>
</template>

<script>
import actions from '@/shared/actions'

export default {
  name: 'app',
  data () {
    return {
      actionToken: ' '}},computed: {
    actionVuexToken () {
      return this.$store.state.tokenModule.token
    }
  },
  mounted () {
    console.log('window.__POWERED_BY_QIANKUN__'.window.__POWERED_BY_QIANKUN__)
    if (window.__POWERED_BY_QIANKUN__) {
      actions.onGlobalStateChange((state, prevState) = > {
        // state: state after the change; PrevState: indicates the status before the change
        console.log('Child app Observer: Token value before change', prevState.token)
        console.log('Child application observer: changed token value is', state.token)

        const { token } = state
        this.actionToken = token
        this.$store.commit('tokenModule/setToken', token)
      }, true)}},methods: {
    setMicroActionToken () {
      if (window.__POWERED_BY_QIANKUN__) {
        actions.setGlobalState({ token: 'microActionToken' })
      }
    },

    setMicroActionVuexToken () {
      if (window.__POWERED_BY_QIANKUN__) {
        actions.setGlobalState({ token: 'microActionVuexToken'})}else {
        this.$store.commit('tokenModule/setToken'.'microActionVuexToken')}}},watch: {
    actionVuexToken (val, oldVal) {
      console.log('The token value before the change in vuex in the child application is', oldVal)
      console.log('The token value changed in the child application vuex is', val)
    }
  }
}
</script>
Copy the code

__POWERED_BY_QIANKUN__ = action + VUex = window.__POWERED_BY_QIANKUN__ = window.

    setMicroActionVuexToken () {
      if (window.__POWERED_BY_QIANKUN__) {
        // Use actions when embedded in the parent application
        actions.setGlobalState({ token: 'microActionVuexToken'})}else {
        // Commit when used independently
        this.$store.commit('tokenModule/setToken'.'microActionVuexToken')}}Copy the code

Microapplications recommend using the route in history mode. The route base should be set to the same value as its activeRule.

To sum up, the above communication methods can be used alone or in combination, depending on the situation.