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

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

⭐前言

大家好,我是yma16,本文分享关于react-grapesjs——源码学习。

该系列往期文章:

react搭建在线编辑html的站点——引入grapes实现在线拖拉拽编辑html

结果演示:

https://yongma16.xyz/react-mjml/

⭐grapesjs初始化过程

源码:https://github.com/GrapesJS/grapesjs

目录结构

运行源码

💖 渲染大体流程

💖 Editor对象 创建
  1. new Editor进入 Editor对象
  2. class Editor implements IBaseModule 执行构造函数 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 pages
   if (config.components && !config.pageManager) {
     config.pageManager = { pages: [{ component: config.components }] };
   }
   // Load modules
   deps.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 modules
    deps.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 required
    const model = new Model({ targets: [] });
    this.model = model;
    // Triggers for the selection refresh and properties
    const 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 event
    const trgCustom = debounce(() => this.__trgCustom(), 0);
    model.listenTo(em, `${evLayerSelect} ${evTarget}`, trgCustom);
    // Other listeners
    model.on('change:lastTarget', () => em.trigger(evTarget, this.getSelected()));
  }


react-grapesjs——开源代码学习与修改(初出茅庐)(二)https://developer.aliyun.com/article/1492697

目录
相关文章
|
前端开发 JavaScript 小程序
7 款最棒的开源 React UI 库测评 - 特别针对国内使用场景推荐
优秀的 React UI 组件库,帮我们节省开发时间,提高开发效率,统一设计语言。更棒的是内置的功能复杂,我们自己很难处理的常用组件,比如表格、表单、富文本编辑器、时间日期选择器、实时拖拽组件等,再进一步,还有帮我们把组件的轮子装好的 React admin 后台管理系统。本文推荐 7 款适用于中文使用者习惯的开源 React UI 库,特别针对国内使用场景推荐。
1060 0
|
7月前
|
IDE 程序员 编译器
react-grapesjs——开源代码学习与修改(初出茅庐)(二)
react-grapesjs——开源代码学习与修改(初出茅庐)
97 0
|
编解码 前端开发 JavaScript
分享几个上千的React开源库助你玩转React
分享几个上千的React开源库助你玩转React
|
前端开发 API
前端(十五)——开源一个用react封装的图片预览组件
前端(十五)——开源一个用react封装的图片预览组件
232 0
|
设计模式 前端开发 JavaScript
组件库设计 | React组件库Concis开源探索过程中的一些心路历程
本文可能无法从细节层面教会你如何做好一个开源组件库,作者也在不断探索和学习,但是也许会对你有所启发。这篇文章既是分享,也是记录,在写这篇文章的此刻,已经是作者一拍脑袋要做一个开源项目将近半年时间了。半年前作者对于如何开发一个组件库一无所知,对于开源项目也是了解甚少,抱着什么不会学什么的态度,独自一人踏上了开源之旅。
225 2
组件库设计 | React组件库Concis开源探索过程中的一些心路历程
|
JavaScript 前端开发 Java
Java 后端学习路线;程序员是否一定要参与开源;为什么好多大网站用了 vue/react 还在用 jQuery |极客观点
Java 后端学习路线;程序员是否一定要参与开源;为什么好多大网站用了 vue/react 还在用 jQuery |极客观点
159 0
|
前端开发
支持动图、一键生成,基于 React 的开源像素绘画应用 —— Pixel Art to CSS
支持动图、一键生成,基于 React 的开源像素绘画应用 —— Pixel Art to CSS
296 0
支持动图、一键生成,基于 React 的开源像素绘画应用 —— Pixel Art to CSS
|
前端开发 API 对象存储
为 React 项目工作四年后,我理解了企业开源的真谛
  对企业而言,发布和维护开源项目都是需要耗费大量心力的。在为 React 工作四年后我对此深有体会。我最开始只是一名外部贡献者,加入 React 团队后,又从工程师做起,最终升为团队管理。和大多数的 Facebook 开源项目一样,React 起初只是为内部使用而开发的,见识到它在简化 UI 代码的开发和维护上的作用后,我们决定将它与全世界分享。   事实证明,React 是 Facebook 的一次令人难以置信的成功,而这成功背后也隐藏了巨大的挑战。举例来说,尽管 React 非常受欢迎,但它仍处于一个竞争激烈的领域,这使得我们在开发新版本时需要小心再小心。
150 0
|
1月前
|
前端开发 JavaScript 开发者
颠覆传统:React框架如何引领前端开发的革命性变革
【10月更文挑战第32天】本文以问答形式探讨了React框架的特性和应用。React是一款由Facebook推出的JavaScript库,以其虚拟DOM机制和组件化设计,成为构建高性能单页面应用的理想选择。文章介绍了如何开始一个React项目、组件化思想的体现、性能优化方法、表单处理及路由实现等内容,帮助开发者更好地理解和使用React。
77 9