vue3如何編寫掛載DOM的插件

vue3 跟 vue2 相比,多了一個 app 的概念,vue3 項目的建立也變成了vue

// main.js
import { createApp } from 'vue' import App from './App.vue'
import ElementPlus from 'element-plus' const app = createApp(App) app.use(ElementPlus) // 使用餓了麼框架
app.mount('#app')

因此 Vue.extend 也沒有了。git

vue2建立一個插件:

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建立一個插件:

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 } }

 

對比能夠發現, vue3 的 DOM掛載方式是新建立一個 app 而後調用 mount() 方法插入到頁面中。github

全局方法的掛載方式也從 vue2 的 Vue.prototype 到 vue3 的 App.config.globalProperties。app

除此以外,vue3 的插件若是用 createApp 來建立新的DOM結構插入到頁面的話,與 main.js 中建立的 app 是隔絕開來的,這意味着 main.js 中 use 的組件和公共方法在 這個插件中沒法使用。框架

// myCom.vue
<template>
  <el-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) }

 

上面的例子中,el-button 是沒法正常顯示的,控制檯會報錯:ide

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

 

 因此,若是既想要新建DOM,又要使用main.js全局註冊的組件和方法,那就不能用 createApp,flex

 在請教了 vue3 的開發大佬後,有了如下方案:(issuesthis

 

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 } }

 

 此次沒有建立新的 app,而是經過給 vNode 複製原來 app 的 context,從而達到組件和公共方法共用,spa

 新建立的插件屬性和方法經過 vNode.component.proxy 來訪問。prototype

el-button 也正確的解析出來了

相關文章
相關標籤/搜索