前端开发同学可能会遇到这样一个问题:产品中需要实现某个功能,而常用的组件库中确实有类似功能的组件,比如比如elementui和antd。前端培训但实际上这些组件不一定能满足你的功能,你或多或少需要看如何修改才能满足你的需求。比如我遇到过element-ui中“树形控件”暴露的参数没有我需要的(获取参数);或者我需要在“对话框”组件的主体上添加两个边框等(样式修改);还有“级联选择器”的多选可搜索功能:需要修改级联看板保持展开状态,选中所有子节点时,不显示所有子节点标签,只显示其父节点显示标签(源码中没有此功能)。比如我需要的功能是左起第二个(因为我不想选项太多的时候标签占用太多空间),而原来的组件是左起第一个。我截图了两张对比一下:至于组件库可能需要修改的地方,我分为以下五类供参考:?样式问题?组件暴露的参数和方法不足(存在于源码中))?可利用部分功能,其余功能需自行开发打包?2+组件联动,一体?完全没有配套组件。下面就来详细谈谈这些问题,以及如何解决。如果有什么不满意或者更好的建议,欢迎指出。1、组件样式问题修改单个文件的样式时,以less为例。如果你想修改一个组件的样式,你可以使用/deep/或>>>深度选择你想要修改的样式(这可以帮助你省去一长串的类名)。.dialog-wrapper{/deep/.el-dialog__body{border:solid1px#999;}}如果要修改全局样式,第一种方法,可以在全局样式文件中写样式重写,导入进去主要的。js全局生效。如下:import"./assets/css/index.css";二是按照组件库提供的“自定义主题”教程进行修改,一般组件库都会给出相关教程。2、组件暴露的参数和方法不足。先问一个问题,你怎么知道组件暴露的参数和方法不够用?其实答案很简单:因为看了组件库的源码。当我们想要获取一个组件的某个参数时,首先需要查看文档中提供了哪些Attributes、Events、Methods。如果它满足你的需求,直接使用它。如果你没有你想要的属性和方法,请你去看看源码中提供的没有暴露的,但是我们可以使用的。上面的“Cascader级联选择器”,我想选择一个搜索选项后不关闭看板。在组件的Events和Methods中没有找到控制看板展开的相关方法,如下:但是去github查看组件源码时,发现toggleDropDownVisible()方法控制看板的扩展。所以我在外部使用$refs直接在组件中调用这个方法。具体调用方法如下,这样即使不暴露方法,也可以调用其内部方法:options="options":props="{multiple:true}"filterable>//调用组件及其方法3.一些函数可以使用,其他功能需要自己完成第三类开发封装其实我们用的比较少,毕竟现在的组件库已经很丰富了。但是这一步引发的思考确实很重要。看别人的源码,有助于提高封装组件的水平。当你需要用到一个组件,但是从头开发这个组件复杂且耗时,并且组件库中的这个组件需要添加一些功能给你使用时,你可以考虑把组件库的代码拿来你的本地,修改它。第一步,您需要浏览组件代码以了解其逻辑。看看你需要添加什么代码。如果在vue中,使用computed,watch,或者修改created,mounted,方法可以完成你的功能,那就大胆尝试吧。在element-ui中,其提供的多选可搜索级联组件存在一个问题:当用户选择所有子节点时,不会合并显示父节点。要完成这个功能,经过以上步骤一番摸索,发现需要修改源码才能完成。所以我在原有的多选可搜索级联选择器的基础上做了如下优化:?默认情况下,级联看板会展开,不会折叠@visible-change="blurCascader(true)"//可以触发展开ofmounted(){this.blurCascader(true)}//失去焦点后触发展开级联看板(默认失去焦点后关闭看板)blurCascader(){this.$nextTick(()=>{this.$refs.cascader.toggleDropDownVisible(true)//调用组件内部未暴露的方法})},?选中后搜索显示级联看板,勾选选中节点//响应选中节点,关闭选中看板选择节点后,显示级联看板changecascader(e){this.$refs.cascader.handleDropdownLeave()},?当所有子节点都被选中时,标签只显示一个父节点,不显示所有子节点//获取所有选中的节点getPresetTags(){consttree=this.panel.menus[0]constresult=[]loop(tree)//递归查找选中的节点functionloop(tree=[]){for(leti=0;我<树.length;i++){constchild=tree[i]if(child.checked){//选中状态意味着选中result.push({...child,closable:true})}elseif(child.indeterminate){//不确定state表示待定,是半选child.children&&loop(child.children)}}}this.presentFormatTags=result//获取可显示标签},?deletenode由于我修改了标签的显示,其deleteTag事件也应该重写。deleteTag(index,tag){let_=thisif(tag&&tag.hasChildren){//当删除的节点是父节点时loop(tag.children)functionloop(list){for(leti=0;i
