首先,我们有这样一个需求,希望给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>
能直接这样调用的原因:我们把element的组件注册进了全局vue中。
二、现在我们想对cascader的组件做一些修改,形成自定义组件
比如每一个node节点的文字后面再添加二次修改啦啦啦。
这一操作我们通过修改cascader的源码来实现。
对node_modules/element-ui中文件结构的理解
注册进vue中的element-ui组件使用的是打包后的文件夹:lib
packages、src、types是源码,仅供开发者查阅。
cascader组件结构
cascader主要由四个组件组成
- cascader
- cascader-panel
- cascader-menu
- cascader-node
我们只要聚焦cascader-node即可
三、将node_modules/element-ui/packages中的cascader、cascader-panel组件源码复制出来作为自定义组件
- 将node_modules/element-ui/packages中的cascader和cascader-panel文件夹复制到业务文件中
- 在需要使用这个复制出来的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() {
- 并将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
第二个
原因:cascader.vue和cascader-menu.vue这两个文件使用了node_modules/element-ui/packages中的scrollbar.vue文件,而这个文件是没做es6转es5处理的,所以会报上面的错误。
解决方案:cascader.vue和cascader-menu.vue中使用的scrollbar换成注册进vue中的eui组件。
弄到这里应该是没问题了,运行没问题,页面展示也和直接调用注册在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>
);
}
然后我们看效果
结语
这就实现了将cascader从node_modules/element-ui中复制出来,二次修改后,作为自定义组件在业务代码中使用了。
通过文章教的方式,几乎任何组件都能很简单的复制出来作为自定义组件。