欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

关于vue3编写挂载DOM的插件问题

程序员文章站 2024-01-22 19:57:10
vue3 跟 vue2 相比,多了一个 app 的概念,vue3 项目的创建也变成了所以 vue.extend 也没有了。vue2创建一个插件:vue3创建一个插件:对比可以发现, vue3 的 do...

vue3 跟 vue2 相比,多了一个 app 的概念,vue3 项目的创建也变成了

// 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 也没有了。

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() 方法插入到页面中。

全局方法的挂载方式也从 vue2 的 vue.prototype 到 vue3 的 app.config.globalproperties。

除此之外,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 是无法正常显示的,控制台会报错:

[vue warn]: failed to resolve component: el-button

 所以,如果既想要新建dom,又要使用main.js全局注册的组件和方法,那就不能用 createapp,

 在请教了 vue3 的开发大佬后,有了以下方案:()

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,从而达到组件和公共方法共用,

 新创建的插件属性和方法通过 vnode.component.proxy 来访问。

el-button 也正确的解析出来了

到此这篇关于vue3如何编写挂载dom的插件的文章就介绍到这了,更多相关vue挂载dom插件内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!

相关标签: vue 挂载 dom