不会封装函数式调用组件?也许你卡在了这里

引出

在vue2当中,全局组件比如弹窗组件如何封装呢?

有些小伙伴可能就简单的封装一个,这种功能也是很完备的

不会封装函数式调用组件?也许你卡在了这里_第1张图片

缺点:需要引入额外响应式变量,方法去控制

优点:像el-dialog一样,适合需要定制性更大的场景

那么对于定制性要求更小的场景,因此适合展示较为简单的内容,ElementUI是推荐: messageBox组件,

看下它的用法:

不会封装函数式调用组件?也许你卡在了这里_第2张图片

这种类似于原生alert弹窗的,就是函数式调用,那么如何封装一个这样的组件呢? 下面会一一道来

如何封装?

为什么能this.$alert?

这个官方给出了答案

不会封装函数式调用组件?也许你卡在了这里_第3张图片

就是利用原型链

Vue.prototype.$alert = function(message, title, options){
    // 这里写逻辑
}

$alert当中怎么将弹窗组件创建出来?

看一下脚手架的工程文件,main.js

import Vue from "vue"
import App from "./App.vue"

const vm = new Vue({
    render: (h) => h(App),
});

vm.$mount("#app")

这里的过程其实就是,

  • 创建Vue实例(new Vue)
  • 创建实例的时候,会调用render方法生成vNode(虚拟节点),其中的参数h函数 是一个用来创建 vNode 的辅助函数。能将引入的APP组件,变成vNode
  • 最后实例挂载($mount)到#app这个真实dom当中

其实$alert里面做的事情无非就是这样嘛,将我们的.vue组件,挂载到真实dom下

可以看到el的MessageBox 是挂在body下的

不会封装函数式调用组件?也许你卡在了这里_第4张图片

那么来实现一个自己的Modal

回到之前开头实现Modal,分别3个属性,2个自定义事件

不会封装函数式调用组件?也许你卡在了这里_第5张图片

内部方法构成:

不会封装函数式调用组件?也许你卡在了这里_第6张图片

前面提到了,只需要构造一个用于创建和挂载的函数,然后挂载到Vue.prototype即可全局调用

现在的目标就是构造这样一个函数

新建一个index.js,

 
  
import Vue form 'vue'
import Modal from "./Modal.vue"
export default function $modal (){
        const vm = new Vue({
            render:(h) => h(Modal)
        })
        // 创建游离节点
        const div = document.createElement('div')
        // 放到body上
        document.body.appendChild(div)
        // 将vm挂载到这个节点上
        vm.$mount(div)
}

打印一下这个vm

不会封装函数式调用组件?也许你卡在了这里_第7张图片

可以看到$el这一项是一个注释节点,因为我们设计的是v-if,此时没命中,因此会创建一个注释节点。

此时我们需要将showModal等参数传进去,该怎么办呢?

h函数就派上用场了,它的第2个参数可以传一些配置项(就是.vue里面的配置项)进去

h(Modal,{props:{showModal:true}})

不会封装函数式调用组件?也许你卡在了这里_第8张图片

 

这样子就有渲染Modal了,但这个h函数的第2个参数只能传入包含模板相关属性(例如 propsclassstyle 等),如果要传入方法的话,只能另寻他法了

不会封装函数式调用组件?也许你卡在了这里_第9张图片

救星:VueExtend

所幸Vue提供了Vue.extend

不会封装函数式调用组件?也许你卡在了这里_第10张图片

从官方文档可以看到,extend需要传入一个配置项,但我们Modal.vue组件已经写好了呀,总不能重新写一份到template,或者写一个render函数吧?

知道你很急,但你先别急,此时你就要知道.vue文件,被import引入之后是什么?

.vue组件究竟是啥???

import Modal from './Modal.vue' 之后, 打印一下Modal

不会封装函数式调用组件?也许你卡在了这里_第11张图片

这不就是一个对象,这熟悉的属性名,不就options配置项

回忆一下.vue当中,是怎么写代码的

不会封装函数式调用组件?也许你卡在了这里_第12张图片

同时vue的编译器帮我们把