About the problem of writing plugins for mounting DOM in vue3

About the problem of writing plugins for mounting DOM in vue3

Compared with vue2, vue3 has an additional concept of app, and the creation of vue3 projects has also become

// main.js
import { createApp } from 'vue'
import App from './App.vue'
import ElementPlus from 'element-plus'

const app = createApp(App)
app.use(ElementPlus) // Use the Ele.me framework app.mount('#app')

So Vue.extend is gone too.

Vue2 creates a plugin:

export default function install (Vue) {
  let app = Vue.extend({
    render (h) {
      return h('div', {
        style: {
          display: this.isShow ? 'flex' : 'none'
        }
      })
    }
  })

  let appDom = new app({
    el: document.createElement('div'),
    data: function () {
      return {
        isShow: false
      }
    }
  })

  function show () {
    appDom.isShow = true
  }

  function hide () {
    appDom.isShow = false
  }
  Vue.prototype.$show = show
  Vue.prototype.$hide = hide
  document.body.appendChild(appDom.$el)
}

Vue3 creates a plugin:

import { createApp, h } from 'vue'

export default function install (App) {
  let app = createApp({
    data() {
      return {
        isShow: false,
      }
    },
    render() {
      return h('div', {
        style: {
          display: this.isShow ? 'flex' : 'none'
        }
      })
    }
  })
  
  const vNodeDom = document.createElement('div')
  document.body.appendChild(vNodeDom)
  const vm = app.mount(vNodeDom)

  App.config.globalProperties.$show = function () {
    vm.isShow = true
  }

  App.config.globalProperties.$hide = function () {
    vm.isShow = false
  }
}

By comparison, we can find that the DOM mounting method of vue3 is to create a new app and then call the mount() method to insert it into the page.

The mounting method of global methods also changes from Vue.prototype of vue2 to App.config.globalProperties of vue3.

In addition, if the vue3 plug-in uses createApp to create a new DOM structure and insert it into the page, it is isolated from the app created in main.js, which means that the components and public methods used in main.js cannot be used in this plug-in.

// myCom.vue
<template>
  <el-button>button</el-button>
</template>


// myCom.js
import { createApp, h } from 'vue'
import myCom from './myCom.vue'
export default function install (App) {
  let app = createApp({
    data() {
      return {
        isShow: false
      }
    },
    render() {
      return h(myCom)
    }
  })

  const vNodeDom = document.createElement('div')
  document.body.appendChild(vNodeDom)
  app.mount(vNodeDom)
}

In the above example, el-button cannot be displayed normally, and the console will report an error:

[Vue warn]: Failed to resolve component: el-button

Therefore, if you want to create a new DOM and use the components and methods registered globally in main.js, you cannot use createApp.

After consulting with the developers of vue3, I came up with the following solution: (issues)

import { render, h } from 'vue'
import myCom from './myCom.vue'

export default function install (App) {
  let vNode = h({
    data() {
      return {
        isShow: false,
      }
    },
    render() {
      return h(myCom)
    }
  })

  const vNodeDom = document.createElement('div')
  document.body.appendChild(vNodeDom)
  vNode.appContext = App._context
  render(vNode, vNodeDom)

  App.config.globalProperties.$show = function () {
    vNode.component.proxy.isShow = true
  }

  App.config.globalProperties.$hide = function () {
    vNode.component.proxy.isShow = false
  }
}

This time, a new app is not created. Instead, the context of the original app is copied to the vNode, so that components and public methods can be shared.

The newly created plugin properties and methods are accessed through vNode.component.proxy.

el-button is also parsed correctly

This is the end of this article about how to write a plug-in for Vue3 to mount DOM. For more relevant Vue mounting DOM plug-in content, please search for previous articles on 123WORDPRESS.COM or continue to browse the following related articles. I hope everyone will support 123WORDPRESS.COM in the future!

You may also be interested in:
  • Example code of mounting vue component to global method
  • Vue uses JSEncrypt to implement rsa encryption and mounting method
  • Vue.extend implements the method of mounting to the instance
  • How to mount objects and methods globally in Vue3.0

<<:  MySQL download and installation details graphic tutorial

>>:  CentOS 7 builds hadoop 2.10 high availability (HA)

Recommend

Correct modification steps for Docker's default network segment

background A colleague is working on his security...

Detailed steps to install python3.7 on CentOS6.5

1. Download Python 3 wget https://www.python.org/...

Quickly master the use of Docker to build a development environment

As the platform continues to grow, the project...

Summary of React's way of creating components

Table of contents 1. Create components using func...

HTML tutorial, easy to learn HTML language

1. <body background=image file name bgcolor=co...

How to implement Vue binding class and binding inline style

Table of contents Binding Class Binding inline st...

Vue Element front-end application development: Use of API Store View in Vuex

Table of contents Overview 1. Separation of front...

Sharing some wonderful uses of wxs files in WeChat applet

Table of contents Preface application Filters Dra...

Detailed explanation of three ways to wrap text in el-table header

Table of contents Problem Description Rendering T...

How to use resident nodes for layer management in CocosCreator

CocosCreator version: 2.3.4 Most games have layer...

Native JavaScript carousel implementation method

This article shares the implementation method of ...

Is your website suitable for IE8?

During the Olympic Games, IE 8 Beta 2 will be rele...

Swiper.js plugin makes it super easy to implement carousel images

Swiper is a sliding special effects plug-in built...

Detailed explanation of making shooting games with CocosCreator

Table of contents Scene Setting Game Resources Tu...