对element-ui的组件二次修改-自定义组件

5,919 阅读4分钟

首先,我们有这样一个需求,希望给element-ui(后面简称eui)的cascader组件的每个节点的文本后面后添加一些特殊文本,而且这个修改得在组件上面弄,而不是在业务代码里面弄。

那么这就属于对eui组件的二次修改。

想要实现这种需求有三种方式:

  • 由于我们项目是通过npm引入的eui的,所以我们可以给eui的github项目提pr,只要官方同意的话,这样就能将新增的功能在eui的最新版本就会出现。但是这样过程很长,而且魔改类pr一般都不给过。
  • 既然eui的包不行,那我们就github复制eui的代码,然后新增功能后,通过npm发布出一个新的eui,姑且称之为aui吧!,然后我们通过npm引入aui,这样cascader就有新功能了。但是这样得维护这个aui了,如果你们公司有理想,想拥有自己的组件库,那么这方案是最好的。
  • 如果你们公司没有这必要的话,我们也可以在业务代码里,将node_modules/element-ui中的cascader组件拖到业务文件中,然后新增功能,形成自定义组件,然后引入这个新的组件。而这个方法就是本文教的方式。

将element-ui的组件复制出来作为自定义组件

一、首先我们拥有一个前端项目,然后该项目引入了element,并且注册进Vue中

这样我们就能在该项目中正常使用element-ui的组件 比如:使用级联组件

<template>
    <el-cascader
        v-model="value"
        :options="options"
        @change="handleChange"
        :props="{ expandTrigger: 'hover' }">
    </el-cascader>
</template>

image.png

能直接这样调用的原因:我们把element的组件注册进了全局vue中。

二、现在我们想对cascader的组件做一些修改,形成自定义组件

比如每一个node节点的文字后面再添加二次修改啦啦啦

这一操作我们通过修改cascader的源码来实现。

对node_modules/element-ui中文件结构的理解

image.png

注册进vue中的element-ui组件使用的是打包后的文件夹:lib

packages、src、types是源码,仅供开发者查阅。

cascader组件结构

cascader主要由四个组件组成

  • cascader
  • cascader-panel
  • cascader-menu
  • cascader-node

image.png

我们只要聚焦cascader-node即可

三、将node_modules/element-ui/packages中的cascader、cascader-panel组件源码复制出来作为自定义组件

  1. 将node_modules/element-ui/packages中的cascader和cascader-panel文件夹复制到业务文件中

image.png

  1. 在需要使用这个复制出来的cascader组件的地方(我这里是App.vue),引入其作为自定义组件
<template>
  <div class="block">
    <new-cascader
      v-model="value"
      :options="options"
      @change="handleChange"
      :props="{ expandTrigger: 'hover' }">
    </new-cascader>
  </div>
</template>
<script>
import NewCascader from './components/cascader/src/cascader.vue'
export default {
  components:{NewCascader},
  data() {
  1. 并将cascader.vue中对cascader-panel.vue的引用改成复制出来的cascader-panel
<script>
/* eslint-disable */
import Popper from 'element-ui/src/utils/vue-popper';
import Clickoutside from 'element-ui/src/utils/clickoutside';
import Emitter from 'element-ui/src/mixins/emitter';
import Locale from 'element-ui/src/mixins/locale';
import Migrating from 'element-ui/src/mixins/migrating';
import ElInput from 'element-ui/packages/input';
import ElTag from 'element-ui/packages/tag';
import ElScrollbar from 'element-ui/packages/scrollbar';
// import ElCascaderPanel from 'element-ui/packages/cascader-panel';
import ElCascaderPanel from '../../cascader-panel/src/cascader-panel.vue';

做完上面两个替换之后应该会报错

第一个:

Can't resolve 'core-js/modules/es6.number.constructor'

解决方案:

npm i core-js@2.6.9 --save

第二个

image.png

原因:cascader.vue和cascader-menu.vue这两个文件使用了node_modules/element-ui/packages中的scrollbar.vue文件,而这个文件是没做es6转es5处理的,所以会报上面的错误。

解决方案:cascader.vue和cascader-menu.vue中使用的scrollbar换成注册进vue中的eui组件。

image.png

image.png

弄到这里应该是没问题了,运行没问题,页面展示也和直接调用注册在vue上的eui组件效果是一样的了。

四、接下来,我们对cascader-node做修改

在cascader-node.vue文件中找到renderContent函数

renderContent(h) {
    const { panel, node } = this;
    const render = panel.renderLabelFn;
    const vnode = render
      ? render({ node, data: node.data })
      : null;

    return (
      <span class="el-cascader-node__label">{ vnode || node.label }</span>
    );
}

然后我们修改成

renderContent(h) {
    const { panel, node } = this;
    const render = panel.renderLabelFn;
    const vnode = render
      ? render({ node, data: node.data })
      : null;

    return (
      <span class="el-cascader-node__label">{ vnode || node.label + ' 二次修改啦啦啦' }</span>
    );
  }

然后我们看效果

image.png

结语

这就实现了将cascader从node_modules/element-ui中复制出来,二次修改后,作为自定义组件在业务代码中使用了。

通过文章教的方式,几乎任何组件都能很简单的复制出来作为自定义组件。

我的其他的文章里面有很多element组件的二次修改,比如cascader全选操作、大数据量渲染、同层级节点互斥(单选);transfer大数据量渲染、大数据量优化;select超大数据量渲染;input组件支持千分位自自动添加(1,000,000)。

体验地址

有问题的兄弟评论区见

看到这里的看官,请点个赞赞吧