弹窗组件咱们很多时候会援用第三方组件,或者写的并不是很通用,只能在独自页面展现,上面咱们来优雅的书写vue的自定义弹窗组件。
实现弹窗组件
弹窗这类组件的特点是它们在以后vue实例之外独立存在,不能写在以后业务dom内,这样款式不好管制,通用性比拟差。
通常挂载于body,通过js动静生成和勾销。这里就阐明了一个知识点,要求咱们对实例的创立和实例的挂载有肯定的理解。
上面咱们来写个简略例子。
create函数
首先咱们要有个明确思路该怎么做:
1、创立一个create函数。
2、传入一个组件的配置(组件显示自身和它的props参数)。
3、创立它的实例,并将其挂载到body上。
4、最初返回组件实例。
import Vue from 'vue'// Component为传入的组件,props为传入的组件参数export default function create(Component, props) { // 创立实例,每个vue我的项目的入口文件都会用到就不具体阐明了 // $mount()实质是把虚构dom转化为实在dom,这点很重要 const vm = new Vue({ render(h) { return h(Component, { props }) } }).$mount() // 通过vm.$el获取生成的dom,把生成的实在dom插入body中 document.body.appendChild(vm.$el) // 获取根组件实例(这里不了解能够去看下后面的文章vue通信大全) const comp = vm.$children[0] // 弹窗敞开时候调用 comp.remove = () => { // 移除自身 document.body.removeChild(vm.$el) // 开释本人所占资源 vm.$destroy() } // 返回创立的实例 return comp}
看了下面代码,很多人会问出两个问题。
1.咱们在初始化$mount绑定id为app的dom节点上,那么这里咱们想绑定在body不是能够间接写成$mount('body'),这样就不必在用js去appendChild。
答案是不行,因为官网明确阐明了这种办法是笼罩该dom内所有内容所以不行。然而$mount()实质是把虚构dom转化为实在dom,这点很重要。
2.还有些同学会说出extend形式也能够创立组件实例并挂载
是的,上面咱们就来实现一下。
import Vue from 'vue'export default function create(Component, props) { // vue.extend()获取创立实例 const Ctor = Vue.extend(Component) // 创立组件实例,这时失去的是虚构dom,如何转化为实在dom const comp = new Ctor({ propsData: props }) // 后面说到$mount就是这个作用 comp.$mount() // 挂在在body上,这时是comp的dom document.body.appendChild(comp.$el) comp.remove = () => { // 移除自身 document.body.removeChild(comp.$el) // 开释本人所占资源 comp.$destroy() } return comp}
这样写起来是不是更轻便。
传入的显示组件
上面简略写下传入显示组件,也就是上文中的Component参数。这里就不赘述,比较简单。
<template> <div v-if="isShow"> <h3>{{title}}</h3> <p>{{message}}</p> </div></template><script>export default {// 上文中传入的props参数 props: { title: { type: String, default: "" }, message: { type: String, default: "" }, duration: { type: Number, default: 1000 } }, data() { return { isShow: false }; }, methods: { // 调用show办法展现 show() { this.isShow = true; // 应用setTimeout定时敞开 setTimeout(this.hide, this.duration); }, // 隐没后移除本身所占资源 hide() { this.isShow = false; this.remove(); } }};</script>
调用弹窗组件
create()返回的是组件本身实例,调用show()办法天然会调用显示组件外面methods中的show办法,而后就胜利了。
create(Notice, { title: '我是自定义弹窗组件', message: '我胜利呈现了', duration: 3000}).show()
以上只是一个简略的弹窗通用封装,如果想理解的更深刻能够参考element-ui的设计理念,去看看其中源码,置信还会有不少播种。
地址:https://github.com/ElemeFE/el...
组件都在packages外面,能够在这个文件夹里观看源码