17

高产似母猪。。写完上篇看了几集新番就空虚了。。零点时分决定爬起来,趁着清明假期能写多写点。

1.前言

我们知道弹出框都是在触发了某种条件后展示,而一个个的新的弹出框的展示,总是覆盖着上一个弹出框。实现覆盖功能需要保证新的弹出框的z-index要比旧的弹出框的z-index值相等或着更高,为达到这个目的element为所有的弹出框(所有下拉框、提示框、Dialog对话框等等)直接或间接的使用到一个js组件element-ui/src/utils/vue-popper,而这个vue-popper又使用了另一个组件element-ui/src/utils/popup/popup-manager.js

PopupManager

PopupManager中有一个zIndex属性初始值为2000,所有的弹出框的z-index其实都是从这个PopupManager.zIndex中获取的,当要展示一个新的弹出框时,组件便会去获取最新的PopupManager.zIndex,然后为PopupManager.zIndex加1,这样就保证了新的弹出框总是比旧的弹出框z-index大,省去自己一个个设置的麻烦,也减少问题的出现。

2.遇到的问题

element本身的弹出框没有什么问题,问题在于我们擅自使用了element未直接暴露出来的组件,这里以el-select中的select-dropdown.vue为例。

我们通过拷贝el-select源码来定制下拉框的内容和逻辑,一切看起来都很完美,但是有一个致命的问题,自己定制的选择器的下拉框总是会出现时不时无法展示的问题,要疯狂点击才会展示。排查后发现就是z-index的值问题,自定义的下拉框的z-index总是无法跟原生的弹出框z-index同步,原因其实很简单。。。使用的不是同一个PopupManager
原来我们直接复制el-select源码,源码中引入下拉框
import ElSelectMenu from './select-dropdown.vue'
我们修改为
import ElSelectMenu from 'element-ui/packages/select/src/select-dropdown.vue'
再来看select-dropdown.vue源码中对于vue-popper的引用
import Popper from 'element-ui/src/utils/vue-popper'
没毛病,但是其实毛病就出在这引用路径上的src,src就是source源的意思,源码中互相引用没问题,但是我们在项目中使用element组件的使用,并不是来自源码,而是来自源码编译出来的依赖库,是npm模块中lib目录下的文件。所以我们的自定义组件用了一个新的PopupManager对象跟原生element组件不同的PopupManager,导致zIndex不同步,展示错误。

3.解决

复制select-dropdown.vue,将原先
import Popper from 'element-ui/src/utils/vue-popper'
修改为
import Popper from 'element-ui/lib/utils/vue-popper'
el-select改引用为我们修改后的select-dropdown.vue。。。

4.最后

  • 1.es6中import的每个模块都是单例的,同一个对象被所有引用共用
  • 2.引用element中未暴露的组件时,要注意尽量使用lib下的,防止出现类似问题
  • 3.引用npm包的某个文件时时,要注意引用其源码和编译后库的区别

坐死等吃
190 声望183 粉丝