前言
前段时间有同事碰到了个需求,需要el-dialog布局遮罩,而不是全部覆盖。本身他自己写了一个方法实现了,但是感觉还能优化就问了一下我,我就研究了下如何实现,下面就来介绍一下实现思路供大家参考。
修改样式
首先我们要弄清楚el-dialog的遮罩是如何实现的。我们打开一个el-dilalog查看页面元素,然后找到遮罩层:
注意遮罩层是class名字为v-modal的div,而不是el-dialog__wrapper,找对了遮罩层div我们就能查看它的样式。v-modal具体的样式为:
我们只要修改一下top/left属性值就能达到局部遮罩的效果,实现起来也毫不费力嘛。但是我们观察一下会发现,此div是在body里面的,要想v-modal生效就要放到全局样式中,这样一来所有的el-dialog就会受到影响,这肯定是不行的,需要想办法进行优化。如果我们对element组件熟悉一点会想到用自定义类名,级联框等组件都有自定义类名的参数,所以我们先查找一下el-dialog的参数是否有自定义类名这一项。
参数优化
custom-class参数用于dialog的自定义类名,我们把它加上去会发现它是加到了el-dialog的div上,而不是v-modal的div上,很明显此参数不行。再查看一下参数我们会发现modal-append-to-body参数,该参数是个布尔值,设置为false可以将遮罩层添加到父元素上,有了这个参数我们就能更好优化了。
- 将需要局部遮罩的el-dialog用父元素包裹。
- 将modal-append-to-body设置为false,此时v-modal会在父元素内。
- 通过父元素修改v-modal类名的属性值,注意如果我们在组件内并且使用了scoped可以通过样式穿透修改v-modal的属性值。
到此我们就完成了局部遮罩的需求,并且不会全局影响。下面我们就来探索下modal-append-to-body参数的原理,打开源码找到该参数。此参数就在props中,而dialog的component混入了Popup在这里我们能找到该参数的用法。
通过三目运算进行判断,为false就会传dom,dom就是当前的$el。接下来我们看下openModal里面的处理:
- if else进行判断,nodeType为11表示的是DocumentFragment类型。
- 参数为false的时候会传dom,只要parentNode满足条件通过appendChild将遮罩层等dom添加进去,否则就会添加到body里面。
知道了该参数的实现原理,如果其他组件也有类似需求但是没有对应的参数我们可以按照此思路进行实现。
总结
以上就是局部遮罩实现过程,主要利用了modal-append-to-body参数,组件库支持的功能还是挺多的,小需求我们从参数入手往往会事半功倍。