开源组件的定制化修改及优化过程记录

在日常开发中常常有这种情况, 使用了某个ui组件库,但是因为功能需求,ui设计等原因,需要对组件进行较大的修改或者定制化开发.这时需要如何正确的修改或者开发呢?

修改组件源码的3种方式

一、组件源码修改 修改引入的lib文件,lib文件夹是组件打包编译后的文件夹,所以直接修改其中对应代码后保存运行即可看到效果。 以常用的element-ui为例

  1. 首先需要找到对应的组件文件夹 node_modules/element-ui/packages/ 下需要的组件
  2. 查看组建.vue文件,找到其中需要修改的位置。
  3. 我们的项目是引入打包编译后的lib文件夹,所以修改 packages 里的组件是不生效的。所以应要在lib文件找到需要修改组件的对应.js中进行代码调整。

但是这种方法往往只能本地临时测试使用,而且很不方便,毕竟lib中都是编译过后的代码,阅读起来不够直观

方式二:拷贝组件文件进行修改引用

  1. 找到组件文件进行拷贝,对于拷贝后的文件代码进行修改。然后进行引用这样引用后既可满足需求,又不会影响原组件的使用。 2.首先找到需要修改文件在node_modules位置然后复制到项目的component中
  2. 完成相关修改操作,在需要使用的文件中引入、注册、使用
js 复制代码
import Tree from 'element-ui' // 之前引用目录

import Tree from '@/compoment/tree/src/tree.vue';  //引入本地文件

如果每次修改都需要复制一份出来,往往会使得我们的代码模块十分臃肿,还会增大了打包的体积 方式三:clone后维护一个自己的组件,并在发布

  1. 还是以elemnt-ui为例,可以在官方的开源代码中fork到自己的仓库中方便维护,然后clone到本地进行相关源代码的修改
  2. 使用 npm run dist即可打出对应lib
  3. 进行本地软连接, 在本地elemnt-ui项目中使用 npm link 或者 yarn link,
  4. 在需要的项目中使用npm linkelemnt-ui,此时就可以进行相关调试
  5. 在本地element项目中使用npm login npm publish 进行发包
  6. 在需要的项目中引入发布的包,不再使用elemnt官方包,修改packjson中的包版本之后npm unlink elemnt-ui npm install重新安装依赖

有相关的定制需求,或者组件暴露出来的方法,事件不能满足相关需求时,我推荐采用第三种方法

代码的优化

利用谷歌浏览器的performance来进行代码的优化

找出耗时函数console.time,console.timeEnd来打印对应函数方法对比耗时时间以我业务的其中一段代码为例

优化前

js 复制代码
processTreeData(data) {
    const arr = [];
    let index = 0;
    for (const key in data) {
        if (Object.hasOwnProperty.call(data, key)) {
            //  处理库数据
            let tableData = data[key];
            arr.push({
                id: `$ {key}. * `,
                //自定义数据唯一标识,防止数据标识重复
                label: key,
                children: []
            });
            //处理表数据
            tableData.forEach((item) = >{
                arr[index].children.push({
                    id: `$ {key}.$ {item}`,
                    //点的空格是数据要求,不可删除
                    label: `$ {key}.$ {item}`,
                    parent: `$ {key}. * `
                });
            });
            index++;
        }
    }
    this.$nextTick(() = >{
        this.warehouseTableData = arr; //树形结构数据
    });
},

优化后

js 复制代码
processTreeData(data) {
    const keys = Object.keys(data);
    let arr = [];
    const batchSize = 100; // 每批处理的数据量
    let currentIndex = 0;
    const processBatch = () = >{
        const batchKeys = keys.slice(currentIndex, currentIndex + batchSize);
        const batchItems = batchKeys.flatMap((key) = >{
            const tableData = data[key];
            const parentId = `$ {key}. * `;

            const childItems = tableData.map((item) = >({
               id: `$ {key}.$ {item}`,
               label: `$ {key}.$ {item}`,
               parent: parentId
            }));

            return [{
                id: parentId,
                label: key,
                children: childItems
            }];
        });

        arr.push(...batchItems);

        currentIndex += batchSize;

        if (currentIndex < keys.length) {
            requestAnimationFrame(processBatch);
        } else {
            this.finishProcessing(arr);
            arr = [];
        }
    };
    requestAnimationFrame(processBatch);
},

finishProcessing(arr) {
   //finish operate
},

分批处理数据

如果data数据很大,可能导致内存溢出和Minor GC阻塞渲染进程的问题。垃圾回收过程会占用主线程资源,导致渲染进程被阻塞。

将数据分成多个较小的批次进行处理,而不是一次性处理整个数据集。这可以通过使用 setTimeout 或 requestAnimationFrame来分批处理数据。循环处理每个批次的数据,并在处理完一个批次后延迟一小段时间处理下一个批次.比如可以将数据分成每批100条,每批处理完后延迟10毫秒,以避免阻塞主线程。

processBatch函数用于处理一批数据。它会根据当前的currentIndex从keys数组中选择一批数据进行处理,并将结果存入arr数组。然后,currentIndex增加,检查是否还有剩余数据需要处理。如果还有剩余数据,则通过requestAnimationFrame调度下一个异步任务来处理下一批数据。如果所有数据处理完成,则进行后续操作。

使用递归调用和requestAnimationFrame可以确保数据处理过程在异步任务中进行,在每一帧中调用 processBatch 函数,给渲染进程更多的时间进行渲染

一旦处理完所有数据,调用 finishProcessing 函数,并进行视图更新

相关推荐
可乐鸡翅yeah_7 小时前
AES‑128 加密 M3U8,IV 初始化向量新手容易踩坑
前端·网络·数据库·ffmpeg·音视频·m3u8在线
MetWeave7 小时前
机场天气的"广播系统":三种报文一次讲明白
前端
xieter7 小时前
【技术精选】深入浅出现代前端渲染与性能优化实践指南 (2026-10-04)
前端·javascript
计算机魔术师7 小时前
Anthropic 密会宗教领袖谈 Claude 意识,OpenAI 为什么急眼
前端
xieter7 小时前
【硬核实战】TypeScript Compiler API: Preserving Child Node Narrowing in Reusable Type Guards 🔧 (2026-10-03)
前端·javascript
xieter7 小时前
【硬核实战】React 19 useFormStatus Returning False? I Built a SubmitButton That Fixes It (2026-10-03)
前端·javascript
Helix2508 小时前
Chrome 性能优化实战:内存节省、硬件加速与 Flags 设置,让浏览器更流畅
chrome·google·性能优化·内存占用·硬件加速·设置技巧·浏览器优化
Data analyse4569 小时前
Cookie过期引发UV上涨的复核方法
服务器·前端·数据分析·uv
paopaokaka_luck9 小时前
非遗文物数字化小程序(AI非遗问答、ONNX图像识别、协同过滤推荐、ECharts数据分析、非遗知识浏览与互动、文创商城订单闭环、文化活动报名签到、社区交流)
javascript·spring boot·mysql·数据分析·echarts·mybatis
Highcharts.js9 小时前
图表开发实战总结| 7 条“黄金法则”与“性能铁律”
前端·javascript·vue.js·编辑器·时序数据库·highcharts