这款国外开源框架, 让你轻松构建自己的页面编辑器

开源
乍眼一看我们可能会认为它只是一个页面/HTML 编辑器,但它能做的不仅仅如此。GrapesJS 是一个多用途的 Web 页面搭建框架,这意味着它允许我们轻松创建一个支持拖放的任何具有类似 HTML 结构的构建器。它所包含的内容远不止网页。

[[416380]]

按照我一向的写作风格,我会在下面列出文章的大纲,以便大家有选择且高效率的阅读和学习:

  • GrapesJS 框架基本介绍
  • 如何使用 GrapesJS 构建 web 编辑器
  • 基于 GrapesJS 构建的开源网页编辑器 craft.js
  • 更多可视化编辑器推荐

基本介绍

chrome-capture.gif

乍眼一看我们可能会认为它只是一个页面/HTML 编辑器,但它能做的不仅仅如此。GrapesJS 是一个多用途的 Web 页面搭建框架,这意味着它允许我们轻松创建一个支持拖放的任何具有类似 HTML 结构的构建器。它所包含的内容远不止网页。我们使用类似 HTML 的结构的场景有:

  • 时事通讯(例如 MJML)
  • 原生移动应用程序(例如 React Native)
  • 本机桌面应用程序(例如 Vuido)
  • PDF (例如 React PDF)

并且 GrapesJS 附带的功能和工具使我们能够制作易于使用的编辑器。这使用户无需任何编码知识即可创建复杂的类似 HTML 的模板。

同时 GrapesJS 官网上还给我们提供了3个不同场景的案例, 我们可以参考这些案例快速制作属于我们自己的web编辑器:

  • Webpage Builder
  • Newsletter Builder
  • Newsletter Builder with MJML

那么至于这些搭建框架的实现原理, 我之前的文章中也做了很多剖析和设计, 大家如果感兴趣可以参考研究一下, 接下来我们看看如何安装和使用它.

如何使用 GrapesJS 构建 web 编辑器

1. 安装

我们可以用 umd 的方式来导入:

<link rel="stylesheet" href="//unpkg.com/grapesjs/dist/css/grapes.min.css"
<script src="//unpkg.com/grapesjs"></script> 
  • 1.
  • 2.

也可以通过 npm 来安装:

npm i grapesjs -S 
  • 1.

之后我们可以通过如下方式导入到项目:

import 'grapesjs/dist/css/grapes.min.css'
import grapesjs from 'grapesjs'
  • 1.
  • 2.

2. 第一个demo

在安装完之后, 我们先实现一个基本的页面编辑demo:

chrome-capture (1).gif

相关代码如下:

<html> 
  <head> 
    <link rel="stylesheet" href="//unpkg.com/grapesjs/dist/css/grapes.min.css"
    <script src="//unpkg.com/grapesjs"></script> 
    <style> 
        #gjs { 
          border: 3px solid #444; 
        } 
        .gjs-cv-canvas { 
          top: 0; 
          width: 100%; 
          height: 100%; 
        } 
    </style> 
  </head> 
  <body> 
    <div id="gjs"
      <h1>Hello World Component!</h1> 
    </div> 
    <script> 
       const editor = grapesjs.init({ 
          container: '#gjs'
          // 我们也可以使用可选的: `components: '<h1>Hello World Component!</h1>'`, 
          fromElement: true
          // 编辑器尺寸 
          height: '300px'
          width: 'auto'
          // 禁用存储管理, 下面的文章我会介绍 
          storageManager: false
          panels: { defaults: [] }, 
         }); 
    </script> 
  </body> 
</html> 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.

这样就实现了一个简单的编辑器, 是不是很简单呢? 我们接下来继续探索更强大的功能。

3. 添加和定义组件

我们都知道网页编辑器需要提供非常丰富的组件, 这样能帮助用户更轻松的搭建页面, 同样 grapesjs 支持添加各种自定义组件, 也内置了常用的基础组件, 我们来看一个 demo :

chrome-capture (2).gif

由以上 demo 我们可以看到添加了3个基本组件: 区块, 文本, 图片。基本实现代码如下:

const editor = grapesjs.init({ 
  // ...其他配置 
  blockManager: { 
    appendTo: '#blocks'
    blocks: [ 
      { 
        id: 'section'
        label: '<b>Section</b>',  
        attributes: { class:'gjs-block-section' }, 
        content: `<section
          <h1>H5-Dooring</h1> 
          <div>积木式搭建H5页面</div> 
        </section>`, 
      }, { 
        id: 'text'
        label: 'Text'
        content: '<div data-gjs-type="text">My Baby</div>'
      }, { 
        id: 'image'
        label: 'Image'
        selecttrue
        content: { type: 'image' }, 
        activate: true
      } 
    ] 
  }, 
}); 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.

由代码我们可以发现我们只需要在 blockManager 的 blocks 里添加指定的组件即可。同时我们还可以动态的添加组件:

editor.BlockManager.add('my-block-id', { 
    // ...其他配置如label 
    content: { 
        tagName: 'div'
        draggable: false
        attributes: { 'some-attribute''some-value' }, 
        components: [ 
          { 
            tagName: 'span'
            content: '<b>DooringX</b>'
          }, { 
            tagName: 'div'
            components: '<span>无限可能</span>'
          } 
        ] 
      } 
}) 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.

至于更详细的组件配置文档, 大家可以参考文档: grapesjs组件如何工作

image.png

4. 添加功能面板

仅仅实现组件添加还不够, 一个有尊严的编辑器还应该有各种功能按钮, 来实现不同用户的需求。

现在我们有了画布和自定义组件,让我们看看如何创建一个功能面板,里面有按钮(使用Panels API)。

chrome-capture (3).gif

我们可以看到顶部有3个功能按钮:

  • 是否显示组件边线
  • 显示源码
  • 显示json

首先我们需要定义用来展示功能面板的元素(样式可以自定义):

<div class="panel__top"
    <div class="panel__basic-actions"></div> 
</div> 
  • 1.
  • 2.
  • 3.

其次我们来定义挂载功能面板:

editor.Panels.addPanel({ 
  id: 'panel-top'
  el: '.panel__top'
}); 
editor.Panels.addPanel({ 
  id: 'basic-actions'
  el: '.panel__basic-actions'
  buttons: [ 
    { 
      id: 'visibility'
      active: true
      className: 'btn-toggle-borders'
      label: '<u>B</u>'
      command: 'sw-visibility'
    }, { 
      id: 'export'
      className: 'btn-open-export'
      label: 'Exp'
      command: 'export-template'
      context: 'export-template',  
    }, { 
      id: 'show-json'
      className: 'btn-show-json'
      label: 'JSON'
      context: 'show-json'
      command(editor) { 
        editor.Modal.setTitle('Components JSON'
          .setContent(`<textarea style="width:100%; height: 250px;"
            ${JSON.stringify(editor.getComponents())} 
          </textarea>`) 
          .open(); 
      }, 
    } 
  ], 
}); 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.

我们可以定义更多的功能, 大家可以参考文档来学习使用。

5. 添加图层管理面板

在处理 Web 元素时,我们可能会发现另一个常见的工具是图层管理器。它是树状结构的,使我们能够轻松地对页面元素进行管理。要启用它,我们只需指定要渲染它的位置:

const editor = grapesjs.init({ 
  // ... 
  layerManager: { 
    appendTo: '.layers-container' 
  }, 
  // 我们能定义一个默认的面板作为侧边图层管理器 
  panels: { 
    defaults: [{ 
      id: 'layers'
      el: '.panel__right'
      // 定义面板能否拖拽 
      resizable: { 
        maxDim: 350, 
        minDim: 200, 
        tc: 0, 
        cl: 1, // 左侧可拖拽 
        cr: 0, 
        bc: 0, 
        keyWidth: 'flex-basis'
      }, 
    }] 
  } 
}); 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.

效果如下:

chrome-capture (4).gif

我们可以看到右侧的图层面板, 可以轻松管理我们页面上的元素。

6. 添加样式配置面板

样式面板也很简单, 我们先定义对应的容器:

<div class="panel__right"
    <div class="layers-container"></div> 
    <div class="styles-container"></div> 
</div> 
  • 1.
  • 2.
  • 3.
  • 4.

然后初始化对应的配置脚本:

const editor = grapesjs.init({ 
  // ... 
  panels: { 
    defaults: [ 
      // ... 
      { 
        id: 'panel-switcher'
        el: '.panel__switcher'
        buttons: [{ 
            id: 'show-layers'
            active: true
            label: 'Layers'
            command: 'show-layers'
            // Once activated disable the possibility to turn it off 
            togglable: false
          }, { 
            id: 'show-style'
            active: true
            label: 'Styles'
            command: 'show-styles'
            togglable: false
        }], 
      } 
    ] 
  }, 
  selectorManager: { 
    appendTo: '.styles-container' 
  }, 
  styleManager: { 
    appendTo: '.styles-container'
    sectors: [{ 
        name'Dimension'
        openfalse
        buildProps: ['width''min-height''padding'], 
        properties: [ 
          { 
            type: 'integer'
            name'The width'
            property: 'width',  
            units: ['px''%'],  
            defaults: 'auto',  
            min: 0,  
          } 
        ] 
      },{ 
        name'Extra'
        openfalse
        buildProps: ['background-color''box-shadow''custom-prop'], 
        properties: [ 
          { 
            id: 'custom-prop'
            name'Custom Label'
            property: 'font-size'
            type: 'select'
            defaults: '32px'
            options: [ 
              { value: '12px'name'Tiny' }, 
              { value: '18px'name'Medium' }, 
              { value: '32px'name'Big' }, 
            ], 
         } 
        ] 
      }] 
  }, 
}); 
 
// 定义指令 
editor.Commands.add('show-layers', { 
  getRowEl(editor) { return editor.getContainer().closest('.editor-row'); }, 
  getLayersEl(row) { return row.querySelector('.layers-container') }, 
 
  run(editor, sender) { 
    const lmEl = this.getLayersEl(this.getRowEl(editor)); 
    lmEl.style.display = ''
  }, 
  stop(editor, sender) { 
    const lmEl = this.getLayersEl(this.getRowEl(editor)); 
    lmEl.style.display = 'none'
  }, 
}); 
editor.Commands.add('show-styles', { 
  getRowEl(editor) { return editor.getContainer().closest('.editor-row'); }, 
  getStyleEl(row) { return row.querySelector('.styles-container') }, 
 
  run(editor, sender) { 
    const smEl = this.getStyleEl(this.getRowEl(editor)); 
    smEl.style.display = ''
  }, 
  stop(editor, sender) { 
    const smEl = this.getStyleEl(this.getRowEl(editor)); 
    smEl.style.display = 'none'
  }, 
}); 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.
  • 88.
  • 89.
  • 90.
  • 91.
  • 92.
  • 93.

我们可以看看配置后的效果:

chrome-capture (5).gif

7. 更多用法演示

除了以上介绍的功能, 我们还能实现:

  • 定义响应模式(pc, 移动, ipad),
  • 设置存储和加载数据的模式
  • 自定义主题
  • 国际化 i18n 支持

这里就不一一介绍了, 我们直接看一下配置后的演示效果:

chrome-capture (6).gif

基于 GrapesJS 构建的开源网页编辑器 craft.js

那么 GrapesJS 还有很多有意思的功能我们可以挖掘, 接下来我和大家分享一款基于GrapesJS 二次封装的一个开源编辑器框架 craft.js。

chrome-capture (7).gif

我们可以使用它插件化的搭建我们自己的编辑器, 如下是一个应用在React中的例子:

import {Editor, Frame, Canvas, Selector} from "@craftjs/core"
// 定义本文组件 
import {useNode} from "@craftjs/core"
 
const TextComponent = ({text}) => { 
  const { connectors: {drag} } = useNode(); 
 
  return ( 
    <div ref={drag}> 
      <h2>{text}</h2> 
    </div> 
  ) 

 
// 初始化编辑器 
const App = () => { 
  return ( 
    <div> 
      <Editor> 
        // 可编辑的区域 
        <Frame resolver={TextComponent, Container}> 
          <Canvas> 
            <TextComponent text="趣谈前端 - 徐小夕" /> 
          </Canvas> 
        </Frame> 
      </Editor> 
    </div> 
  ) 

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.

更多可视化编辑器推荐

  • h5-Dooring | H5编辑器, 积木式搭建H5页面
  • v6.dooring | 可视化大屏搭建解决方案
  • craft | 基于React的拖拽页面生成器
  • dooringx-lib | 快速高效搭建可视化拖拽平台

最后

后期我会在数据可视化和工程化上输出更多实用的开源项目和框架,如果有其他问题或需求,可以和笔者交流学习。

本文转载自微信公众号「趣谈前端」,可以通过以下二维码关注。转载本文请联系趣谈前端公众号。

 

责任编辑:武晓燕 来源: 趣谈前端
相关推荐

2021-01-21 16:03:15

Java文本编辑器编程语言

2020-04-09 14:23:44

PythonMarkdown编辑器

2022-01-10 18:16:24

编辑器Typora Markdown

2022-04-15 09:59:08

Lexical开源Meta

2020-09-18 06:00:51

开源Markdown编辑器

2020-10-14 12:29:51

开源图表 开发

2011-10-31 10:17:05

插件

2019-06-10 11:06:04

JavaScript编辑器HTML5

2017-05-23 19:19:16

开源Markdown编辑器

2023-12-15 09:59:14

开源GIF编辑器图片格式

2020-08-22 07:46:58

Photoflare开源图像编辑器

2020-12-21 13:33:00

medit编辑器Linux

2019-06-18 09:40:57

Graviton开源代码编辑器

2022-03-20 18:12:03

Shotcut开源视频编辑器

2019-06-14 15:28:13

程序员文本编辑器

2024-04-03 08:22:54

代码编辑器组件

2024-02-21 16:40:06

Web代码编辑器开源

2020-03-25 14:16:58

文本编辑器语言开发

2011-01-10 16:17:49

2022-06-12 16:05:22

vimLinux
点赞
收藏

51CTO技术栈公众号