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

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 的开发大佬后,有了以下方案:(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
  }
}

这次没有创建新的 app,而是通过给 vNode 复制原来 app 的 context,从而达到组件和公共方法共用,

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

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

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

时间: 2021-07-25

一篇文章告诉你如何编写Vue插件

目录 什么是插件 编写插件 使用插件 总结 什么是插件 在Vue框架中,如果需要给Vue增加一些我们需要的功能,Vue给我留了一个插件的方式,我们可以编写自己的插件,然后在Vue中去注册插件,然后去使用他. 通过Vue插件我们可以实现一些Vue框架没有的功能,也可以使用别人写好的插件,来帮助我们更快速的实现一些功能. 插件的功能范围并没有严格的要求,根据官方的示例来说,一般有下面几种: 1.添加全局方法或者属性,如:vue-custom-element,我们可以用插件方式添加一些全局组件,然后可

vuex 中插件的编写案例解析

1.第一步 const myPlugin = store => { // 当 store 初始化后调用 store.subscribe((mutation, state) => { // 每次 mutation 之后调用 // mutation 的格式为 { type, payload } }); }; 2.第二步 const store = new Vuex.Store({ // ... plugins: [myPlugin] }); 二.编写一个打印日志的插件 1.函数的书写 import

基于Vuejs和Element的注册插件的编写方法

1.首先要在HTML文档中引入jQuery版本2.0以下的.一个vuejs库 一个Element-UI库 <script src="js/jquery-1.11.0.min.js"></script> <script src="js/vue.js"></script> <script src="js/Element-UI.js"></script> 2.HTML的布局  &l

详解使用webpack打包编写一个vue-toast插件

本文介绍了使用webpack打包编写一个vue插件,分享给大家.具体如下: 一.说明: 需求:创建一个toast插件 思路:利用vue组件创建模板,使用webpack打包生成插件再全局使用. # 项目目录: |_ package.json |_ webpack.config.js |_ .babelrc |_ dist |_ src |_ index.html |_ lib |_ index.js |_ vue-toast.vue 1.1 webpack基础 1.基础插件 - html-webp

使用vue-cli编写vue插件的方法

利用vue组件创建模板,使用webpack打包生成插件再全局使用 1.vue init webpack-simple 生成项目目录 2.调整目录结构 3.修改webpack.config.js var path = require('path') var webpack = require('webpack') module.exports = { entry: './src/index.js', output: { path: path.resolve(__dirname, './dist')

vue购物车插件编写代码

本文实例为大家分享了vue购物车插件的具体代码,供大家参考,具体内容如下 先上效果图 下面相关代码: <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Hello MUI</title> <meta name="viewport" content="width=device-width, initial-sca

vue上传图片组件编写代码

本文实例教大家如何编写一个vue上传图片组件,具体如下 1.首先得有一个[type=file]文件标签并且隐藏,changge事件来获取图片: <input @change="fileChange($event)" type="file" id="upload_file" multiple style="display: none"/> 2.触发隐藏的文件标签:(通过原生的click来触发) document.ge

vue弹窗插件实战代码

vue做移动端经常碰到弹窗的需求, 这里写一个功能简单的vue弹窗 popup.vue <template> <div class="popup-wrapper" v-show="visible" @click="hide"> <div class="popup-text">{{text}}</div> </div> </template> 组件html结

在vue项目中使用codemirror插件实现代码编辑器功能

在vue项目中使用codemirror插件实现代码编辑器功能(代码高亮显示及自动提示),具体内容如下所示: 1.使用npm安装依赖 npm install --save codemirror; 2.在页面中放入如下代码 <template> <textarea ref="mycode" class="codesql" v-model="code" style="height:200px;width:600px;&quo

vue的滚动条插件实现代码

这篇文章主要介绍了vue的滚动条插件实现代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 效果如下 代码如下 <template> <div class="vue-scroll" ref="vueScrollW"> <div class="vue-scroll-w" ref="vueScroll" > <div class=&quo

vue打印插件vue-print-nb的实现代码

1.引入插件npm install vue-print-nb --save 在main.js中引入 import Print from 'vue-print-nb'Vue.use(Print) 2.html代码 <div class="box"> <div id="printTest" class="upTable"> <table> <tr> <td class="title&qu

typecho插件编写教程(五):核心代码

之前啰嗦了很多,现在开始写核心代码. 分析一下,发布文章的时候,我们需要的信息就是当前文章的URL,我们需要想办法从$contents. $class中拿到他. 目前我们的插件类代码如下(请注意render被我改成了send) 复制代码 代码如下: class BaiduSubmitTest_Plugin implements Typecho_Plugin_Interface { public static function activate(){         //挂载发布文章和页面的接口

vue中插件和组件的区别点及用法总结

本教程操作环境:windows7系统.vue2.9.6版,DELL G3电脑. 一.组件是什么 回顾以前对组件的定义: 组件就是把图形.非图形的各种逻辑均抽象为一个统一的概念(组件)来实现开发的模式,在Vue中每一个.vue文件都可以视为一个组件 组件的优势 降低整个系统的耦合度,在保持接口不变的情况下,我们可以替换不同的组件快速完成需求,例如输入框,可以替换为日历.时间.范围等组件作具体的实现 调试方便,由于整个系统是通过组件组合起来的,在出现问题的时候,可以用排除法直接移除组件,或者根据报错

解决vue.js在编写过程中出现空格不规范报错的问题

找到build文件夹下面的webpack.base.conf.js文件. 然后打开该文件,找到图下这段代码,把他注释掉. 注释掉之后,再进行子页面等编写的时候,空格不规范的情况下也不会再报错啦.因为这个报错对于初学者来说实在头大.哈哈O(∩_∩)O哈哈~ 我标注的这些地方,原本是有严格的空格规范要求的,这些报错真是另人烦躁呀o(╥﹏╥)o 反正我把这个问题解决了,特别开心哒哒哒~~~ 以上这篇解决vue.js在编写过程中出现空格不规范报错的问题就是小编分享给大家的全部内容了,希望能给大家一个参考

深入解析js轮播插件核心代码的实现过程

轮播效果在网页中用的很多,swiper是其中最有代表性的作品,它支持水平和竖直滑动,还有反弹效果,兼容移动端和pc端.当然代码量也是相当大的,单是js就有5300行(3.4.0的未缩版本),若不考虑代码利用率和加载速度直接就用了,在移动端比较慎重,比如京东(m.jd.com)的轮播就没有用它,而是自己实现了类似的功能,代码量很少的样子(格式化之后看起来二三百行左右的样子).那么这个功能如果自己来实现,要怎么做呢? 准备工作 1. 准备几张图片(我这里放了四张) 2. 搭建目录结构(html+cs