被迫使用Vue的Extends修改Element UI源码,都是为了前台小姐姐

67 阅读3分钟

前言

场景一

领导:小周啊,有领导反映这个弹窗选择了文字,拖出弹窗后,弹窗就关闭了,这个你要看看,很影响操作啊

我:这个是正常现象,当前使用的组件库就是这样的,因为点击了这个空白处就会自动关闭弹窗的。

领导:这个还是要改进一下,你看看有没有什么办法

我:改不了啊,这组件原先就这样,我又不是这个组件的开发者,又不是我说算

领导:那你看看有没有其他的组件库参考参考啊,整天顶嘴,信不信下个就把你优化了,整天这做不了那做不了的

tzvvh-oaazk.gif

场景二

ui:这个分页器要严格按照设计稿的产出,这部分审核不通过

我:这个组件库就这是这样的,不支持修改里边的元素的,可以修改文字,但是你又加上自己的图标,这又不是react可以随意插入元素

ui:搞不来是嘛?

我:搞不来

ui:行,那我跟领导反馈一下

我心里是一万个tm的

领导:小周啊,这你又做不了?

组件库:

image.png

设计:

QQ图片20231227145413.png

领导:这两需求要是做好了,我把前台新来那个长腿黑丝小姐姐介绍给你

我:艹!你早这么说不就好了。

开始学习Element UI源码

既然官方文档没有介绍,作为一名成熟的小白,只能去看源码有没有什么办法了

首先要了解的是,这个dialog是怎么去关闭,关闭相关逻辑是怎么样的一个流程

于是,找到这段代码

image.png

这下就有办法了,只要再关闭操作之前我们进行校验,校验当前的情况下是否可以继续进行源码操作,相当于拦截了,半路杀出个程咬金,好家伙,小姐姐是志在必得了,嘻嘻

微信图片_20231227151505.jpg

Vue的extends

简单理解为,你可以继承一个vue组件,然后覆盖或者叠加属性的方法

image.png

Dialog Extends实现逻辑

需要获取到我们能的一个鼠标点下和放开的元素是否都包含在弹窗内,如果包含在弹窗内,继续执行原有操作,否则拦截中断

创建MyDialog.vue文件

<script>
import { Dialog } from "element-ui";
export default {
  name: "MyDialog",
  extends: Dialog,
  data() {
    return {
      m_mousedownTarget: false,
      m_mouseupTarget: false,
    };
  },
  mounted() {
    // document.addEventListener("click", this.onBodyClick);
    document.addEventListener("mousedown", this.handleMousedown);
    document.addEventListener("mouseup", this.handleMouseup);
  },
  destroyed() {
    // document.removeEventListener("click", this.onBodyClick);
    document.removeEventListener("mousedown", this.handleMousedown);
    document.removeEventListener("mouseup", this.handleMouseup);
  },
  methods: {
    handleMousedown(e) {
      this.m_mousedownTarget = this.getIsPoppercontains(e);
    },
    handleMouseup(e) {
      this.m_mouseupTarget = this.getIsPoppercontains(e);
    },
    getIsPoppercontains(e) {
      const dialogElm = this.$refs.dialog;
      if (dialogElm.contains(e.target)) {
        return "dialogElm";
      } else {
        return "other";
      }
    },
    hide(cancel) {
      if (this.m_mousedownTarget !== this.m_mouseupTarget) {
        return;
      }
      if (cancel !== false) {
        this.$emit("update:visible", false);
        this.$emit("close");
        this.closed = true;
      }
    },
  },
};
</script>

使用,跟官方文档一样使用,属性也是相同的

image.png

如果是想直接使用el-dialog作为组件名的话

只需要在main.js中重新注册一下组件即可

Vue.component('ElDialog', Dialog)

vg8ay-a9myf.gif

Table Extends修改

修改表格也是如此,利用extends找到相应的逻辑进行修改继承使用

<script>
import { Pagination } from 'element-ui'
export default {
  name: 'FormListPagination',
  extends: Pagination,
  components: {
    Prev: {
      render() {
        return (
          <button
            type="button"
            class="btn-prev"
            disabled={
              this.$parent.disabled || this.$parent.internalCurrentPage <= 1
            }
            on-click={this.$parent.prev}>
            {this.$parent.prevText ? (
              <span>{this.$parent.prevText}</span>
            ) : (
              <span>
                <SvgIcon name="icona-fanhui15x" />
                上一页
              </span>
            )}
          </button>
        )
      }
    },
    Next: {
      render() {
        return (
          <button
            type="button"
            class="btn-next"
            disabled={
              this.$parent.disabled ||
              this.$parent.internalCurrentPage ===
                this.$parent.internalPageCount ||
              this.$parent.internalPageCount === 0
            }
            on-click={this.$parent.next}>
            {this.$parent.nextText ? (
              <span>{this.$parent.nextText}</span>
            ) : (
              <span>
                下一页
                <SvgIcon name="icona-qianjin15x" />
              </span>
            )}
          </button>
        )
      }
    }
  }
}
</script>

来自同事的责怪

瞧瞧你用vue的extends干了好事,这下好啦,我们都要去修改了,

但是,我有长腿黑丝小姐姐,我不不在乎

结语

我是周星星,一个经历vue2vue3reactflutter,最终回归vue2的作死型前端选手。

JS DOM编程笔记 - 详解鼠标事件(十六)