引言
页面引用弹出框组件是经常碰见的需求,如果强行将弹出框组件放入到页面中,虽然功能上奏效但没有实现组件与页面间的解耦,非常不利于后期的维护和功能的扩展.下面举个例子来说明一下这种做法的弊端.
@click="openModal()">点击
:is_open="is_open" @close="close()"/>
import Modal from "../components/Modal/Modal";//外部引入的弹出框组件export default {
components: {
Modal, }, data(){
return {
is_open:false //控制弹出框关闭或打开 } }, methods: {
openModal() {
//显示弹出框 this.is_open = true; }, close(){
//子组件触发的事件,关闭弹出框 this.is_open = false; } },};
Modal是外部引入的弹出框组件,父组件通过is_open
来控制弹出框的隐藏和显示.仔细分析上述结构存在的问题如下.
•Modal组件被硬编码,强行在父组件的components
里面注册并在父组件的模板中渲染.设想一下,一个弹出框组件就需要在父组件中写一次,5个弹出框也都要在父组件的模板里写五个.这样会让父组件的页面结构变的复杂不利于阅读,其次弹出框组件应该与父组件解耦,它不应该写死在父组件的模板中.•父组件需要单独设置一个状态
is_open
来控制弹出框的显示和隐藏,假如父组件需要引入多个弹出框,那势必也要定义多个状态来对弹出框进行控制.
为了实现弹出框和父组件的解耦,最理想的方式是运用函数式编程的思想,在父组件内只需要调用一个函数就可以让弹出框显示出来,接下来看一下如何实现.
弹出框组件的处理
我们接下来实现一个代码十分简单但功能强大的工具函数,借助它就可以将弹出框组件封装起来.如果父组件需要使用哪个弹出框组件直接调用函数就能轻松显示或者隐藏.
实现
import Vue from 'vue';export const createModal = (Component, props) => {
const vm = new Vue({
render: (h) => h(Component, {
props, }), }).$mount(); document.body.appendChild(vm.$el); const ele = vm.$children[0]; ele.destroy = function() {
vm.$el.remove(); ele.$destroy(); vm.$destroy(); }; return ele;};
•Component
就是父组件调用的弹出框组件,在这里作为参数传入.props
是最终传递给弹出框组件内部的props
•new
一个 Vue
实例,render
属性对应的函数里,h
的作用是将弹出框组件变成虚拟dom•$mount
一定要调用,它会将虚拟dom转换成真实的dom元素•vm.$el
就是对应到传入的弹出框组件Component
所渲染的真实dom,将它挂载到body下面,此时页面