文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

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

2024-12-02 23:58

关注

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

基本介绍

chrome-capture.gif

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

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

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

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

如何使用 GrapesJS 构建 web 编辑器

1. 安装

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

  1. "stylesheet" href="//unpkg.com/grapesjs/dist/css/grapes.min.css"
  2. "//unpkg.com/grapesjs"

也可以通过 npm 来安装:

  1. npm i grapesjs -S 

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

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

2. 第一个demo

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

chrome-capture (1).gif

相关代码如下:

  1.  
  2.    
  3.     "stylesheet" href="//unpkg.com/grapesjs/dist/css/grapes.min.css"
  4.     "//unpkg.com/grapesjs"
  5.      
  6.    
  7.    
  8.     "gjs"
  9.        
  10.     
 
  •      
  •    
  •  
  • 这样就实现了一个简单的编辑器, 是不是很简单呢? 我们接下来继续探索更强大的功能。

    3. 添加和定义组件

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

    chrome-capture (2).gif

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

    1. const editor = grapesjs.init({ 
    2.   // ...其他配置 
    3.   blockManager: { 
    4.     appendTo: '#blocks'
    5.     blocks: [ 
    6.       { 
    7.         id: 'section'
    8.         label: 'Section',  
    9.         attributes: { class:'gjs-block-section' }, 
    10.         content: `<section
    11.            
    12.           
      积木式搭建H5页面
       
    13.         section>`, 
    14.       }, { 
    15.         id: 'text'
    16.         label: 'Text'
    17.         content: 'My Baby
    '
  •       }, { 
  •         id: 'image'
  •         label: 'Image'
  •         selecttrue
  •         content: { type: 'image' }, 
  •         activate: true
  •       } 
  •     ] 
  •   }, 
  • }); 
  • 由代码我们可以发现我们只需要在 blockManager 的 blocks 里添加指定的组件即可。同时我们还可以动态的添加组件:

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

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

    image.png

    4. 添加功能面板

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

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

    chrome-capture (3).gif

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

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

    1. "panel__top"
    2.     "panel__basic-actions"
    3.  

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

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

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

    5. 添加图层管理面板

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

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

    效果如下:

    chrome-capture (4).gif

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

    6. 添加样式配置面板

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

    1. "panel__right"
    2.     "layers-container"
    3.     "styles-container"
    4.  

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

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

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

    chrome-capture (5).gif

    7. 更多用法演示

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

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

    chrome-capture (6).gif

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

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

    chrome-capture (7).gif

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

    1. import {Editor, Frame, Canvas, Selector} from "@craftjs/core"
    2. // 定义本文组件 
    3. import {useNode} from "@craftjs/core"
    4.  
    5. const TextComponent = ({text}) => { 
    6.   const { connectors: {drag} } = useNode(); 
    7.  
    8.   return ( 
    9.      
    10.       

      {text}

       
    11.      
    12.   ) 
    13.  
    14. // 初始化编辑器 
    15. const App = () => { 
    16.   return ( 
    17.     
       
    18.        
    19.         // 可编辑的区域 
    20.          
    21.            
    22.             "趣谈前端 - 徐小夕" /> 
    23.            
    24.          
    25.        
    26.      
    27.   ) 

    更多可视化编辑器推荐

    最后

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

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

     

    来源: 趣谈前端内容投诉

    免责声明:

    ① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

    ② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

    软考中级精品资料免费领

    • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

      难度     813人已做
      查看
    • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

      难度     354人已做
      查看
    • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

      难度     318人已做
      查看
    • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

      难度     435人已做
      查看
    • 2024年上半年系统架构设计师考试综合知识真题

      难度     224人已做
      查看

    相关文章

    发现更多好内容

    猜你喜欢

    AI推送时光机
    位置:首页-资讯-后端开发
    咦!没有更多了?去看看其它编程学习网 内容吧
    首页课程
    资料下载
    问答资讯