react-grapesjs——开源代码学习与修改(初出茅庐)

文章目录

    • ⭐前言
    • ⭐grapesjs初始化过程
      • 💖 渲染大体流程
        • 💖 Editor对象 创建
        • 💖 EditorModel 对象创建
        • 💖 load modules 加载定义的目录模块Module
        • 💖 StyleManager渲染过程
    • ⭐修改grapesjs配置项
    • ⭐总结
      • ⭐ 如何修改开源代码
      • ⭐如何高效阅读开源代码
    • ⭐结束

yma16-logo

⭐前言

大家好,我是yma16,本文分享关于react-grapesjs——源码学习。
该系列往期文章:
react搭建在线编辑html的站点——引入grapes实现在线拖拉拽编辑html
结果演示:
https://yongma16.xyz/react-mjml/
demo

⭐grapesjs初始化过程

源码:https://github.com/GrapesJS/grapesjs
目录结构
dir
运行源码
在这里插入图片描述

💖 渲染大体流程

💖 Editor对象 创建

  1. new Editor进入 Editor对象
  2. class Editor implements IBaseModule<EditorConfig> 执行构造函数 constructor
  constructor(config: EditorConfig = {}, opts: any = {}) {this.config = {...defaults,...config,pStylePrefix: config.stylePrefix ?? defaults.stylePrefix,};this.em = new EditorModel(this.config);this.$ = opts.$;this.em.init(this);this.editor = this.em;}

💖 EditorModel 对象创建

  1. class EditorModel extends Model 执行构造函数
  constructor(conf: EditorConfig = {}) {super();this._config = conf;const { config } = this;this.set('Config', conf);this.set('modules', []);this.set('toLoad', []);this.set('storables', []);this.set('selected', new Selected());this.set('dmode', config.dragMode);const { el, log } = config;const toLog = log === true ? keys(logs) : isArray(log) ? log : [];bindAll(this, 'initBaseColorPicker');if (el && config.fromElement) {config.components = el.innerHTML;}this.attrsOrig = el? toArray(el.attributes).reduce((res, next) => {res[next.nodeName] = next.nodeValue;return res;}, {} as Record<string, any>): '';// Move components to pagesif (config.components && !config.pageManager) {config.pageManager = { pages: [{ component: config.components }] };}// Load modulesdeps.forEach(constr => this.loadModule(constr));storableDeps.forEach(constr => this.loadStorableModule(constr));this.on('change:componentHovered', this.componentHovered, this);this.on('change:changesCount', this.updateChanges, this);this.on('change:readyLoad change:readyCanvas', this._checkReady, this);toLog.forEach(e => this.listenLog(e));// Deprecations[{ from: 'change:selectedComponent', to: 'component:toggled' }].forEach(event => {const eventFrom = event.from;const eventTo = event.to;this.listenTo(this, eventFrom, (...args) => {this.trigger(eventTo, ...args);this.logWarning(`The event '${eventFrom}' is deprecated, replace it with '${eventTo}'`);});});}

💖 load modules 加载定义的目录模块Module

deps的类型

const deps: (new (em: EditorModel) => IModule)[] = [UtilsModule,I18nModule,KeymapsModule,UndoManagerModule,StorageManager,DeviceManager,ParserModule,StyleManager,SelectorManager,ModalModule,CodeManagerModule,PanelManager,RichTextEditorModule,TraitManager,LayerManager,CanvasModule,CommandsModule,BlockManager,
];
    // Load modulesdeps.forEach(constr => this.loadModule(constr));

💖 StyleManager渲染过程

路径 src/style_manager

在这里插入图片描述

构造函数

constructor(em: EditorModel) {super(em, 'StyleManager', new Sectors([], { em }), stylesEvents, defaults);bindAll(this, '__clearStateTarget');const c = this.config;const ppfx = c.pStylePrefix;if (ppfx) c.stylePrefix = ppfx + c.stylePrefix;this.builtIn = new PropertyFactory();this.properties = new Properties([], { em, module: this });this.sectors = this.all; // TODO check if (module: this) is requiredconst model = new Model({ targets: [] });this.model = model;// Triggers for the selection refresh and propertiesconst ev = 'component:toggled component:update:classes change:state change:device frame:resized selector:type';this.upAll = debounce(() => this.__upSel(), 0);model.listenTo(em, ev, this.upAll as any);// Clear state target on any component selection change, without debounce (#4208)model.listenTo(em, 'component:toggled', this.__clearStateTarget);// Triggers only for properties (avoid selection refresh)const upProps = debounce(() => {this.__upProps();this.__trgCustom();}, 0);model.listenTo(em, 'styleable:change undo redo', upProps);// Triggers only custom eventconst trgCustom = debounce(() => this.__trgCustom(), 0);model.listenTo(em, `${evLayerSelect} ${evTarget}`, trgCustom);// Other listenersmodel.on('change:lastTarget', () => em.trigger(evTarget, this.getSelected()));}

⭐修改grapesjs配置项

屏蔽 views的两个按钮
原来的样式
init

panels/config配置
change-panels
更改配置项 注释不需要的配置

import { PanelProperties } from '../model/Panel';const swv = 'sw-visibility';
const expt = 'export-template';
const osm = 'open-sm';
const otm = 'open-tm';
const ola = 'open-layers';
const obl = 'open-blocks';
const ful = 'fullscreen';
const prv = 'preview';interface ButtonProps {id?: string;active?: boolean;togglable?: boolean;className?: string;command?: string | (() => any);context?: string;attributes?: Record<string, any>;
}interface PanelProps extends Omit<PanelProperties, 'id' | 'buttons'> {id?: string;buttons?: ButtonProps[];
}export interface PanelsConfig {stylePrefix?: string;/*** Default panels.*/defaults?: PanelProps[];
}const config: PanelsConfig = {stylePrefix: 'pn-',defaults: [{id: 'commands',buttons: [{}],},{id: 'options',buttons: [{active: true,id: swv,className: 'fa fa-square-o',command: 'core:component-outline',context: swv,attributes: { title: 'View components' },},{id: prv,className: 'fa fa-eye',command: prv,context: prv,attributes: { title: 'Preview' },},{id: ful,className: 'fa fa-arrows-alt',command: ful,context: ful,attributes: { title: 'Fullscreen' },},{id: expt,className: 'fa fa-code',command: expt,attributes: { title: 'View code' },},],},{id: 'views',buttons: [{id: osm,className: 'fa fa-paint-brush',command: osm,active: true,togglable: false,attributes: { title: 'Open Style Manager' },},// {//   id: otm,//   className: 'fa fa-cog',//   command: otm,//   togglable: false,//   attributes: { title: 'Settings' },// },// {//   id: ola,//   className: 'fa fa-bars',//   command: ola,//   togglable: false,//   attributes: { title: 'Open Layer Manager' },// },{id: obl,className: 'fa fa-th-large',command: obl,togglable: false,attributes: { title: 'Open Blocks' },},],},],
};export default config;

修改成功!
result
同理合并配置项也是合并配置module的代码可以实现

⭐总结

⭐ 如何修改开源代码

修改开源代码的步骤如下:

  1. 首先要获取并安装开发环境。这包括编译器、文本编辑器和版本控制软件等。

  2. Fork开源项目,即在GitHub或其他代码托管平台上复制一份项目,这样你就有了自己的独立分支。

  3. 在你的本地机器上克隆你所Fork的项目。通过clone命令将整个项目下载到你的本地机器上。

  4. 创建新的分支。你需要创建一个新的分支,以便你可以在不影响其他贡献者的情况下进行更改。

  5. 对代码进行修改。使用你的文本编辑器打开项目文件并进行所需的更改,完成后保存文件。

  6. 运行测试。运行项目的测试套件,确保你的修改没有破坏现有代码的功能。

  7. 提交修改。使用git提交修改到你的本地分支并将这些更改推送到你的Fork仓库。

  8. 发送一个合并请求。你可以向原始项目的所有者发送一个请求,请求将你的分支合并到他们的主分支上。

以上是修改开源代码的基本步骤,需要结合实际情况进行具体操作。在修改开源代码时,不仅要尊重原作者的版权,还要了解开源授权协议及相应的规定。

⭐如何高效阅读开源代码

阅读开源代码可以帮助你学习其他程序员的技术,尤其是在你遇到类似的问题时,可以参考开源代码中的解决方案。以下是一些高效阅读开源代码的技巧:

  1. 了解项目结构:先了解项目的目录结构和代码风格,可以帮助你更快地定位代码位置和理解代码。

  2. 建立索引:可以使用工具或者手动建立索引,以便于更快地查找关键代码和内容。

  3. 浅阅读:先快速浏览代码,了解项目的整体结构和大致流程。

  4. 深度阅读:对于关键的代码部分,进行深度阅读,仔细理解其实现和作用。

  5. 调试代码:在自己的环境中运行代码,通过调试来理解代码的执行过程和实际效果。

  6. 参考文档:阅读开源项目的文档和介绍,可以更好地理解代码和项目。

  7. 学习工具:学习使用开源代码的工具,如IDE、版本控制软件等,可以更好地理解和使用开源代码。

最重要的是,在阅读开源代码时,要注重理解代码的思路和设计方式,而不是仅仅复制代码。

⭐结束

本文分享到这结束,如有错误或者不足之处欢迎指出!
light

👍 点赞,是我创作的动力!
⭐️ 收藏,是我努力的方向!
✏️ 评论,是我进步的财富!
💖 最后,感谢你的阅读!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/69322.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

外贸爬虫系统

全球智能搜索 全球智能搜索 支持全球所有国家搜索引擎&#xff0c;及社交平台&#xff0c;精准定位优质的外贸客户&#xff0c;免翻墙 全球任意国家地区实时采集 搜索引擎全网邮箱电话采集 社交平台一键查看采集&#xff08;Facebook,Twitter,Linkedin等&#xff09; 职位…

基于 Flink CDC 构建 MySQL 和 Postgres 的 Streaming ETL

官方网址&#xff1a;https://ververica.github.io/flink-cdc-connectors/release-2.3/content/%E5%BF%AB%E9%80%9F%E4%B8%8A%E6%89%8B/mysql-postgres-tutorial-zh.html官方教程有些坑&#xff0c;经过自己实测&#xff0c;记录个笔记。 服务器环境&#xff1a; VM虚拟机&am…

【个人博客系统网站】我的博客列表页 · 增删改我的博文 · 退出登录 · 博客详情页 · 多线程应用

【JavaEE】进阶 个人博客系统&#xff08;4&#xff09; 文章目录 【JavaEE】进阶 个人博客系统&#xff08;4&#xff09;1. 增加博文1.1 预期效果1.1 约定前后端交互接口1.2 后端代码1.3 前端代码1.4 测试 2. 我的博客列表页2.1 期待效果2.2 显示用户信息以及博客信息2.2.1…

关于CS144的小总结

文章目录 字节流接收方需要完成的工作处理数据封装头部 发送方需要完成的工作发送数据处理收到的报文段头部发送但未确认队列处理超时重传处理 为什么需要三次握手流程角度1&#xff1a;确认连接双方能力角度2&#xff1a;避免半连接 为什么需要4次挥手流程4次挥手的目的为什么…

【C语言每日一题】10. 超级玛丽游戏

题目来源&#xff1a;http://noi.openjudge.cn/ch0101/10/ 10 超级玛丽游戏 总时间限制: 1000ms 内存限制: 65536kB 问题描述 超级玛丽是一个非常经典的游戏。请你用字符画的形式输出超级玛丽中的一个场景。 输入 无。 输出 如样例所示。 样例输入 &#xff08;无&…

Kotlin管道Channel在receiveAsFlow时debounce与flow差异

Kotlin管道Channel在receiveAsFlow时debounce与flow差异 import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.delay import kotlinx.coroutines.flow.* import kotlinx.coroutines.launch import kotlinx.coroutine…

kafka学习-概念与简单实战

目录 1、核心概念 消息和批次 Topic和Partition Replicas Offset broker和集群 生产者和消费者 2、开发实战 2.1、消息发送 介绍 代码实现 2.2、消息消费 介绍 代码实现 2.3、SpringBoot Kafka pom application.yaml KafkaConfig producer consumer 1、核心…

【Spring MVC】统一功能处理

一、登录验证 登录验证通过拦截器实现&#xff0c;拦截器就是在用户访问服务器时&#xff0c;预先拦截检查一下用户的访问请求。 没有拦截器时&#xff0c;用户访问服务器的流程是&#xff1a;用户–>controller–>service–>Mapper。有拦截器时&#xff0c;用户访问…

RouterOS-配置PPPoEv4v6 Server

1 接口 ether3 出接口 ether4 内网接口 2 出接口 出接口采用PPPoE拨号SLAAC获取前缀&#xff0c;手动配置后缀 2.1 选择出接口interface&#xff0c;配置PPPoE client模式 2.2 配置PPPoE client用户名和密码 2.3 从PPPoE client获取前缀地址池 2.4 给出接口选择前缀并配置…

第10章_索引优化与查询优化(覆盖索引, 索引下推等)

4. 子查询优化 MySQL 从 4.1 版本开始支持子查询&#xff0c;使用子查询可以进行 SELECT 语句的嵌套查询&#xff0c;即一个 SELECT 查询的结果作为另一个SELECT 语句的条件。 子查询可以一次性完成很多逻辑上需要多个步骤才能完成的 SQL 操作 。 子查询是 MySQL 的一项重…

Vue + Element UI 前端篇(七):功能组件封装

组件封装 为了避免组件代码的臃肿&#xff0c;这里对主要的功能部件进行封装&#xff0c;保证代码的模块化和简洁度。 组件结构 组件封装重构后&#xff0c;试图组件结构如下图所示 代码一览 Home组件被简化&#xff0c;包含导航、头部和主内容三个组件。 Home.vue <te…

Qt 常用函数

设置编码 #if (QT_VERSION < QT_VERSION_CHECK(5,0,0)) #if _MSC_VERQTextCodec *codec QTextCodec::codecForName("gbk"); #elseQTextCodec *codec QTextCodec::codecForName("utf-8"); #endifQTextCodec::setCodecForLocale(codec);QTextCodec::se…

vue优化首屏加载时间优化-cdn引入第三方包

前言 为什么要进行首屏加载优化&#xff0c;因为随着我们静态资源和第三方包和代码增加&#xff0c;压缩之后包会越来越大 随着网络的影响&#xff0c;在我们第一输入url请求资源时候&#xff0c;网络阻塞&#xff0c;加载时间长&#xff0c;用户体验不好 仔细观察后就会发现…

YOLOV8实例分割——详细记录环境配置、自定义数据处理到模型训练与部署

前言 Ultralytics YOLOv8是一种前沿的、最先进的&#xff08;SOTA&#xff09;模型&#xff0c;它在前代YOLO版本的成功基础上进行了进一步的创新&#xff0c;引入了全新的特性和改进&#xff0c;以进一步提升性能和灵活性。作为一个高速、精准且易于操作的设计&#xff0c;YO…

用Jmeter压测问题解决

最近做一个基于duboo服务的接口&#xff0c;需要进行稳定性测试。但是用Jmeter GUI 方式跑只能持续2个小时左右&#xff0c;Jmeter就崩溃了&#xff0c;日志报错&#xff1a;out of memory 解决方法如下&#xff1a; 直接运行jmeter的java包试试&#xff1a; 1、打开jmeter.…

【计算机网络】http协议

目录 前言 认识URL URLEncode和URLDecode http协议格式 http方法 GET POST GET与POST的区别 http状态码 http常见header 简易的http服务器 前言 我们在序列化和反序列化这一章中&#xff0c;实现了一个网络版的计算器。这个里面设计到了对协议的分析与处…

JVM监控和调优常用命令jps|jstat|jinfo|jmap|jhat|jstack实战

1.JVM监控和调优的主要目的 性能优化:通过JVM调优,可以提高Java应用程序的性能,减少响应时间,提高吞吐量,以更好地满足用户需求。性能优化可以加快应用程序的执行速度,减少延迟,提高用户体验。 内存管理:JVM负责管理Java应用程序的内存。正确的内存管理可以避免内存泄漏…

CKEditor5定制及文件上传

CKEditor4已从2023年6月开始停止支持&#xff0c;所以最好还是升级到CKEditor5。CKEditor5在使用上与CKEditor4在使用层面上还是有很大的不同&#xff0c;首先&#xff0c;CKEditor4完全可以下载包含了所有功能的full包&#xff0c;通过配置选择需要的功能&#xff0c;只有希望…

人们对区块链的认识开始变得深入和完善,另一条新路径开始衍生

当区块链行业的发展进入到深水区&#xff0c;特别是当有关区块链的狂热与躁动开始退场&#xff0c;仅仅只是主打区块链的概念&#xff0c;而没有找到区块链与现实商业联通的方式和方法&#xff0c;依然成为困扰区块链发展的一大症结。   事实上&#xff0c;从区块链被人们认识…

STL常用容器 (C++核心基础教程之STL容器详解)String的API

在C的标准模板库&#xff08;STL&#xff09;中&#xff0c;有多种容器可供使用。以下是一些常见的容器类型&#xff1a; 序列容器&#xff08;Sequential Containers&#xff09;&#xff1a; std::vector&#xff1a;动态数组&#xff0c;支持快速随机访问。 std::list&…