⭐前言
大家好,我是yma16,本文分享关于react-grapesjs——源码学习。
该系列往期文章:
react搭建在线编辑html的站点——引入grapes实现在线拖拉拽编辑html
结果演示:
https://yongma16.xyz/react-mjml/
⭐grapesjs初始化过程
源码:https://github.com/GrapesJS/grapesjs
运行源码
💖 渲染大体流程
💖 Editor对象 创建
- new Editor进入 Editor对象
- 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 对象创建
- 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