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

A method of hiding processes under Linux and the pitfalls encountered

Preface 1. The tools used in this article can be ...

Pure CSS3 realizes the effect of div entering and exiting in order

This article mainly introduces the effect of div ...

Problems encountered when uploading images using axios in Vue

Table of contents What is FormData? A practical e...

js to implement web calculator

How to make a simple web calculator using HTML, C...

Commonly used HTML format tags_Powernode Java Academy

1. Title HTML defines six <h> tags: <h1&...

Usage of mysql timestamp

Preface: Timestamp fields are often used in MySQL...

Realizing tree-shaped secondary tables based on angular

First look at the effect: Code: 1.html <div cl...

How to fill items in columns in CSS Grid Layout

Suppose we have n items and we have to sort these...

The process of deploying and running countly-server in docker in win10

I have just come into contact with and become fam...

What are HTML inline elements and block-level elements and their differences

I remember a question the interviewer asked durin...

How to assign a public IP address to an instance in Linux

describe When calling this interface, you need to...

How to implement a binary search tree using JavaScript

One of the most commonly used and discussed data ...

JS+CSS to realize dynamic clock

This article example shares the specific code of ...