el-dialog、el-drawer里拖拽出总是会自动关闭的问题(下集)

效果预览:

https://sunzsh.github.io/vue-demos/#/dialog-click

demo代码: https://github.com/sunzsh/vue-el-demo/blob/master/src/views/dialog-click.vue

补丁文件:

https://github.com/sunzsh/vue-el-demo/blob/master/src/components/el-overlay-auto-close.js

上期视频咱们分析了这个bug的原因

那今天呢

咱们就来看一下这个bug

解决的全过程

我希望呢这个过程对大家能有所启发

而不仅仅是解决这一个问题

首先呢

我们先来说一下最终想要的效果

因为项目里可能有很

多地方在用这个Dialog

我们希望在那些用的地方

不用做任何修改

所以呢

这也就需要我们去覆盖原来的Dialog

那怎么弄呢

首先我们打开这个main.js

我们希望未来写好这个补丁之后

在这全局导入一次就可以覆盖这个

原生的组件了

所以啊我们在这先导一下

这个组件还没写

所以呢咱们在这先随便起个名字

在这定义好

比如我们叫PATCH_

然后呢叫EL

Overlay因为它不只是Dialog有这个问题

我们可能还要覆盖原来这个

drawer这个抽屉组件

所以呢咱们名字不叫Dialog也不叫drawer

咱们叫这个遮罩层的意思

Overlay然后auto close

然后呢from

呃这个文件现在还没有

所以呢一会咱们就要去写这个文件

咱们先放这哈

然后呢我们用Vue

把它use一下就可以了

好然后接下来的问题

我们就需要把这个文件去写一下

好然后呢我们去这个目录

找到这个文件

在这里

新建

好那这个文件应该怎么写呢

其实也简单

咱们先把它原生的这个组件导进来

我们叫Dialog from element UI

好然后呢我们再声明一个新的

咱们叫DialogPatched

然后里边

什么也不写,咱们就继承原来的组件啊

然后呢

下边explore它

explore它我们直接把这个倒出去

然后里面写install vue

那这里边写什么呢

我们就vue.component

这块我们就可以不用写死

我们可以用原生组件点name

这样的话呢比较动态

你覆盖什么组件

就用这个组件点name就可以了

这样的话呢到此为止

一个基本的

覆盖(ElementUI)原生组件的框架就是这样了

我们可以验证一下

我们在这写一个mounted的

然后呢我们在里边写 clog

比如说

hello

好来看一下

大家看出来了

说明现在这个dialog

用的就是我们继承之后的组件了

然后就简单了

我们就给它扩充功能就好了

那根据昨天这个思路呢

我们首先需要一个变量对吧

所以呢我们在这加一个data

然后呢

我们给它加一个什么属性呢

wrapperMouseDowned

默认是false

好然后呢

我们就需要修改它原生的

这个遮罩层的点击事件

在那里边做一个判断

所以呢我们先去看一下它的源码啊

找到这个dialog点进去

然后呢找到这个vue文件

注意他这有个

click.selft 这个就是那个遮罩层

然后呢就是这个方法

我们就原封不动把这个方法拿过来

做一个覆盖就好了

好然后呢

我们来观察一下他原来这个方法

第一行做了一个忽略

也就是如果用户

关闭了这个“遮罩层点击关闭”的功能

他就return掉

那我们再给加一个或者

或者什么呢

就是遮罩层没有被 mousedown

非 mousedowned 就是遮罩层没有被mousedown

但是触发了click,说明是拖过来的

我们就给他忽略掉

好这个完事了啊

(差一个this)

好这个变量在这能用到了没问题

接下来呢

我们就要给这个变量去设置了

其实也很简单

我们在mounted里去取到this

点EL

就找到这个组件的第一层Dom结构

我们来看一下它代码

第一层dom结构是什么

其实不算这个transition其实就是这个

遮罩层,我们找到这个遮罩层之后呢

给它加一个onmousedown

我们给它加一个点击事件

我们把e拿过来

好这里边怎么写呢

我们直接让this.wrapperMouseDowned等于谁呢

e.target.classList.contains

这个昨天(上一期)咱们说过

contains什么(样式名)?

el-dialog__wrapper

我们来看一下是不是这个

就是这个,好!

这样的话呢我们在

monted的时候

就把这个mousedown绑定好了

这回咱们先来试一下啊

刷新一下

好点击

然后我们点击遮罩层

功能是正常的

然后呢我们点击里边拖出来

松手也没有问题

这样的话呢这个补丁就打好了

我们就以后正常用Dialog就没有问题了

同理呢这个抽屉组件也是一样的做法

我们来试一下啊

首先呢我们把抽屉组件也倒进来

然后呢我们再下把声明(这个就收起来)

我们声明一个DrawerPatched

然后呢我们在里边还是继承子drawer

然后把这一块儿会Vue.component...

这样的话打这个补丁

好然后呢我们先对它

好有了这个是变量呢

我们再来

改造它原来的方法

我们再去看一下Drawer的原码

点到Drawer里

注意看它这一块

在给这个层做点击时间handleWrapperClick

所以我们一会要判断有没有这个类

然后我们先把这个方法覆盖掉哈

把这个方法拿过来

放在下面

(写methods里面)

这个把它粘过来

然后呢这个跟刚才那个不太一样

它是只有在这种情况下才会去关闭

对吧所以我们加一个并且

并且什么呢并且

这个Wrapper被mouse downed

然后呢我们再来加mounted

这里边怎么写呢

我们就:this.

wrapperMouseDowned 等于 e.target.classList

这里边就不能用这个class了

刚才我们说了他用的是

他是给这个加的click

所以我们要判断他有没有这个

粘过来

嗯不对

好我们再来试一下啊

刷新一下

打开抽屉

点击遮罩层

没问题然后

拖出来也没问题了

这样的话呢

这两个补丁就都打好了

以后的话我们项目里

只要把这个文件放到项目里边

然后在main.js把它们Use一下

整个的项目就不会再有类似的问题了

还是老规矩

回头我会把源码提交一下,大家

如果需要的话可以直接来下载

地址大家如果记不住github的话

可以直接记这个1024bugs.com

最后更新于