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…

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…

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

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

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

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

【计算机网络】http协议

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

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

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

宠物电商Chewy第二季度销售额28亿美元,同比增长14.3%

美国宠物电商Chewy公布2023年第二季度财报。报告显示&#xff0c;其Q2季度销售额同比增长14.3%至28亿美元&#xff0c;超出市场预期。 以下为Chewy期内业绩概要&#xff1a; 1.毛利率28.3%&#xff0c;同比增长20个基点 2.净利润有所收窄&#xff0c;同比下降15.2%至1890万美…

9.2.tensorRT高级(4)封装系列-自动驾驶案例项目self-driving-深度估计

目录 前言1. 深度估计总结 前言 杜老师推出的 tensorRT从零起步高性能部署 课程&#xff0c;之前有看过一遍&#xff0c;但是没有做笔记&#xff0c;很多东西也忘了。这次重新撸一遍&#xff0c;顺便记记笔记。 本次课程学习 tensorRT 高级-自动驾驶案例项目self-driving-深度估…

Mybatis学习|Mybatis缓存:一级缓存、二级缓存

Mybatis缓存 MyBatis包含一个非常强大的查询缓存特性&#xff0c;它可以非常方便地定制和配置缓存。缓存可以极大的提升查询效率。 MyBatis系统中默认定义了两级缓存:一级缓存和二级缓存 默认情况下&#xff0c;只有一级缓存开启。(SqlSession级别的缓存&#xff0c;也称为本地…

Leetcode 1572.矩阵对角线元素之和

给你一个正方形矩阵 mat&#xff0c;请你返回矩阵对角线元素的和。 请你返回在矩阵主对角线上的元素和副对角线上且不在主对角线上元素的和。 示例 1&#xff1a; 输入&#xff1a;mat [[1,2,3],[4,5,6],[7,8,9]] 输出&#xff1a;25 解释&#xff1a;对角线的和为&#xff…

qt.qpa.plugin:找不到Qt平台插件“wayland“|| (下载插件)Ubuntu上解决方案

相信大家也都知道这个地方应该做什么&#xff0c;当然是下载这个qt平台的插件wayland,但是很多人可能不知道怎么下载这个插件。 那么我现在要说的这个方法就是针对这种的。 sudo apt install qtwayland5完事儿了奥兄弟们。 看看效果 正常了奥。

JVM类的加载相关的问题

JVM类的加载相关的介绍 学习类的加载的加载过程对深入理解JVM有十分重要的作用&#xff0c;下面就跟我一起学习JVM类的加载过程吧&#xff01; 文章目录 JVM类的加载相关的介绍一、类的加载过程二、双亲委派机制1、类加载器的种类2、为什么JVM要分成不同的类的加载器3、类的加…

机器人中的数值优化(十)——线性共轭梯度法

本系列文章主要是我在学习《数值优化》过程中的一些笔记和相关思考&#xff0c;主要的学习资料是深蓝学院的课程《机器人中的数值优化》和高立编著的《数值最优化方法》等&#xff0c;本系列文章篇数较多&#xff0c;不定期更新&#xff0c;上半部分介绍无约束优化&#xff0c;…