Said in the previous

After the previous article discussed how React and Vue call each other, we discovered new requirements. After Vue3 was upgraded, the existing rich and refined components of Vue2 could not be used directly on Vue3 because the underlying render function was rewritten. Therefore, EMP proposed a scheme to call Vue2 from Vue3 to solve this problem, which was proved feasible in practice.

So we implemented EMp-Vuett, a version of HOC across Vue.

Look at the demo

The demo link:

Git clone emp, Yarn Global add LERna && yarn && rm -rf node_modules/vue && Lerna Bootstrap && CD projects && dev:vue23 will start the following projects: Vue3-project Vue2-base

Call the Vue2 component in Vue3

The Vue2 component itself

use

Install emp – vuett

yarn add @efox/emp-vuett or npm i @efox/emp-vuett

Vue3 calls the Vue2 component

  1. usenpx @efox/emp-cli initCreate a new Vue3 project
  2. Choose Vue3

3. Incorporate it into the project@efox/emp-vuettImport a Vue2 component. 4. Create a null componentdomAnd give an ID. 5. Put Vue2 components and nulldomId the incoming@efox/emp-vuett

Full code use case:

<template>
  <div>
    <h1>VUE 3 Project</h1>
    <v3b-button />
    <! Mount an empty DOM to keep the load order. Pass the id to emp-vuett.
    <div id="content"></div>
    <conent-in-vue3
      :dataProps="num"
      :methodProps="propsFunc"
      @myEvent="emitFunc"
    />
    <v3b-content />
  </div>
</template>

<script>
import { defineAsyncComponent, render } from "vue";
/ / Vue2 components
import Content from "@v2b/Content";
// Vue2 runs HOC on Vue3
import { Vue2InVue3 } from "@efox/emp-vuett";
// Let Vue2 components run on Vue3 via emp-vuett
// Pass in the id of the Vue2 component and an empty div for the current template
const ContentInVue3 = Vue2InVue3(Content, "content");

export default {
  components: {
    "conent-in-vue3": ContentInVue3,
  },
  data() {
    return {
      num: 0}; },methods: {
    // Pass props to Vue2 as normal
    propsFunc() {
      console.log("Vue3 to Vue2 Method Props");
    },
    Emit can be used normally on Vue2 components
    emitFunc() {
      this.num++; }},setup() {},
  mounted() {},
  name: "App"};</script>

Copy the code

On,props,attrs,slot, etc

Note: Because Vue3 removed $Listeners, Vue2 components called by Vue3 need to make the following adjustments

      // Vue2 uses the custom event passed by Vue3 to change the function name kebab-case to camelCase with the prefix on
      // For example, to call @myevent, write onMyEvent
      // called by Vue3
      this.$emit("onMyEvent");
      // called by Vue2
      this.$emit("myEvent");
Copy the code

Emp – vuett principle

EMP remotely invokes the Vue2 component

The aforementioned Vue2 components are all called remotely through the EMP micro front end. To call a component remotely, you only need to reference the project and the referenced project in two steps:

  1. npm i -g @efox/emp-cli or yarn global add @efox/emp-cli

2. Create emp-config.js and configure it.

/vue2-base/emp-config.js

const withVue2 = require('@efox/emp-vue2')
module.exports = withVue2(({config}) = > {
  const projectName = 'vue2Base'
  const port = 8009
  config.output.publicPath(`http://localhost:${port}/ `)
  config.devServer.port(port)
  config.plugin('mf').tap(args= > {
    args[0] = {
      ...args[0],
      ...{
        name: projectName,
        library: {type: 'var'.name: projectName},
        filename: 'emp.js'.exposes: {
          './Content': './src/components/Content',},shared: ['vue/dist/vue.esm.js',}}return args
  })

  config.plugin('html').tap(args= > {
    args[0] = {
      ...args[0],
      ...{
        title: 'EMP Vue2 Base',}}return args
  })
})

Copy the code

/vue3-project/emp-config.js

const withFrameWork = require('@efox/emp-vue3')
module.exports = withFrameWork(({config}) = > {
  const projectName = 'vue3Project'
  config.output.publicPath('http://localhost:8006/')
  config.devServer.port(8006)
  config.plugin('mf').tap(args= > {
    args[0] = {
      ...args[0],
      ...{
        name: projectName,
        library: {type: 'var'.name: projectName},
        filename: 'emp.js'.remotes: {
          '@v2b': 'vue2Base',},exposes: {},
        /* Shared: {vue: {eager: true, singleton: true, requiredVersion: '^3.0.2'},}, */}},return args
  })
  config.plugin('html').tap(args= > {
    args[0] = {
      ...args[0],
      ...{
        title: 'EMP Vue3 Project'.files: {
          js: ['http://localhost:8009/emp.js'],}}},return args
  })
})

Copy the code

conclusion

  1. With EMP support, Vue2 components can be remotely invoked, which greatly facilitates the reuse of components.
  2. Through the use of Vue3 life cycle and Vue2 Runtime to achieve the seamless use of Vue2 components in Vue3, greatly enrich the ecology of Vue3.

The author



Benny Shi


Ken.Xu