Angular 页面构建器

Angular 页面构建器 GrapesJS

为Angular构建一个可视化拖放页面构建器,包含可复用的模块、组件、模板、响应式编辑以及你自己的出版工作流程。

视觉拖拽自定义组件可重复使用的块响应式剪辑你的后台可通过插件扩展

26k+

GitHub 星

1.4M+

npm 下载量/月

100+

GJS.Market 上的插件

$0

许可证费,永远

看看它能正常工作

这就是你的用户会看到的

三个真正的 GrapesJS 编辑器,只有在你要求时才加载。这些演示都不是 Angular 应用——这正是它的意义所在。GrapesJS 渲染成它拥有的容器元素,所以编辑表面看起来和行为都和托管页面的框架一样。

在新标签页中打开

库存编辑器:画布、块、图层树、样式管理器和设备切换器。这是你在添加自己块之前的基础。

grapesjs.com/demo.html免费

加载来自grapesjs.com的第三方实时编辑器。

从这里开始

不用从零开始构建编辑器,也能构建可视化页面

构建页面构建器远不止几个Angular组件。一个生产准备的可视化编辑器需要这些元素,才能发布带有它的页面:

  • 拖拽
  • 画布
  • 组成部分
  • 区块
  • 层次
  • 样式
  • 响应式剪辑
  • 资产管理
  • 模板
  • 项目存储
  • 出口
  • 出版

GrapesJS 为大部分列表中的可视化编辑提供了基础,因此你的 Angular 应用可以将预算花在产品和业务逻辑上。后两者——项目存储地点和页面如何上线——仍留给你,因为它们必须与基础设施匹配。

GrapesJS 核心在 BSD-3-Clause 许可证(版本 0.23.6)下开源,且在任何规模下均无许可费。

探索GrapesJS
建筑

Angular 页面构建器的工作原理

编辑器是你应用内的一个路径,不是它的替代品。编辑层以上的所有内容都保持Angular团队原本放置的位置。

  1. Angular 应用

    让你的产品拥有的所有元素,保持不变。

    • 认证
    • 用户
    • 账单
    • 布线
    • 业务逻辑
  2. 可视化页面构建器

    一个懒惰加载的路由,一个拥有容器的组件,以及一个拥有编辑器实例的服务。

    • 编辑路线
    • 编辑器组件
    • 编辑服务
  3. GrapesJS

    可视化编辑引擎,运行在组件提供的容器内。

    • 画布
    • 组成部分
    • 区块
    • 层次
    • 样式
    • 资产
    • 指挥
  4. 你的后台

    项目数据、上传和发布成果真正存在的地方。

    • 你的API
    • 你的数据库
    • 文件存储

Angular 拥有你的应用程序。GrapesJS 驱动视觉编辑层。

编辑器没有提供任何顶层或底层的内容。正是这个界限让集成变得足够浅,之后可以移除——编辑器永远不会成为你产品的核心。

阅读Angular集成指南
能力

构建可视化编辑器所需的一切

发动机自带的八个子系统。每个都是你自己配置的API,而不是一个你直接接受的黑盒子。

拖拽

用户通过将组件拖到画布上,重新排序并在允许的位置嵌套来构建页面。

组成部分

定义可重复使用的组件类型,它们各自有traits、可丢弃的规则以及你自己的行为。

区块

在调色板中为用户提供预定义的剖面和布局,而不是一堆原始的HTML元素。

样式管理器

让用户通过选择和限制的属性面板自定义排版、间距、颜色和布局。

响应式剪辑

每个断点预览和重新样式页面,使用你定义的设备宽度,而不是固定的设备。

资产

通过资产管理器管理图片和其他项目资产,你可以指向自己的存储。

模板

将已完成的页面保存为可重复使用的起始点,这样下一页就不会是空白。

出口

从编辑器里导出干净的HTML和CSS,或者读取JSON项目,按照你的应用偏好渲染。

本列表中故意没有的:托管、CMS、权限模型和发布基础设施。这些都属于你的应用程序,下面的章节说明它们是如何连接的。

定制化

打造属于你自己的Angular页面构建器体验

通用的网站建设工具很少是大家想要的产品。编辑器的每一层都可以替换成符合你应用的版本。

  1. 你的产品
  2. 自定义组件
  3. 自定义区块
  4. 自定义模板
  5. 自定义命令
  6. 定制UI

每一层都会将编辑器缩小到你的内容模型范围。到了最后一层,用户是在创作你的产品——而不是网站。

注册镜像你自己域对象的组件类型,只暴露后端可操作的 traits,并将其放在块面板的分类下。用户随后使用你的 API 已经理解的定价表或产品网格,而不是用你之后需要解析的任意标记。

register-blocks.tsts
// Your content model, not a generic website element.
editor.Components.addType('pricing-table', {
  isComponent: (el) => el.dataset?.gjsType === 'pricing-table',
  model: {
    defaults: {
      tagName: 'section',
      droppable: false,
      traits: ['plan', 'currency', 'billingPeriod'],
    },
  },
});

editor.Blocks.add('pricing-table', {
  label: 'Pricing',
  category: 'Your design system',
  content: { type: 'pricing-table' },
});

一个组件类型和插入它的块。特性名变成了后端读取的字段。

块与模板

为用户提供合适的构建模块

人们用的编辑和放弃的编辑之间的区别,通常取决于第一天调色板里的内容。

你的区块

  • Hero
  • 功能网格
  • 定价
  • 推荐
  • FAQ
  • 联系方式
  • CTA
  • 页脚

不要让用户从零开始。

创建可重复使用的模块和模板,与你的应用设计系统相匹配,这样用户构建的每一页都已经符合品牌风格且响应式一致。GJS.Market 附带了可以安装的块集和模板管理器,无需从头创作前五十个。

浏览块与模板
存储

将项目保存到你的Angular后端

GrapesJS 将项目序列化到 JSON,然后交给存储适配器。适配器的功能完全由你决定。

  1. GrapesJS project data
  2. Angular HttpClient
  3. Your API
  4. Your backend
  5. Your database

编辑器从不和你的数据库通信。它调用你注册的适配器,适配器调用你已有的API。

storage.tsts
editor.Storage.add('angular-backend', {
  async load() {
    return firstValueFrom(this.http.get(`/api/pages/${this.pageId}`));
  },
  async store(data) {
    return firstValueFrom(this.http.put(`/api/pages/${this.pageId}`, data));
  },
});

grapesjs.init({
  container,
  storageManager: { type: 'angular-backend', autosave: true, stepsBeforeSave: 5 },
});

一个定制的存储适配器,连接到你的API。这里没有任何内容是针对GJS.Market的——这是编辑者有文档的存储合同。

  • 项目数据

    组件、样式、页面和资源序列化为JSON文档,你可以存储在任何列或集合中。

  • 自动保存

    存储管理器可以在可配置的更改次数后保存,而不仅仅是在显式操作时保存。

  • 远程存储

    注册一个自定义适配器,并通过Angular的HttpClient路由加载和存储,使用你自己的拦截器和认证头部。

  • 版本管理

    因为每个存档都是文档,保存历史是后台的决定——编辑不需要知道这件事发生过。

  • HTML/CSS 输出

    当交付路径需要静态输出而非重新渲染时,将渲染标记与项目JSON一起导出。

  • 出版

    已发布页面是一个独立的记录,拥有自己的生命周期。将其与编辑写作的草稿分开。

你可以控制项目数据的存储位置。

出版

从视觉编辑到制作

创作和发布是不同的问题,有不同的失败模式。编辑器解决了第一个问题;第二个问题则留在你的基础设施中,缓存、权限和回滚都已经存在。

  1. 创作
  2. 编辑
  3. 保存
  4. 影评
  5. 发布
  6. 实时页面

已发表成果可以去的地方

  • CMS

    把输出写回你组织已经运行的内容系统。

  • REST API

    把项目或渲染的标记发布到拥有验证和权限的端点。

  • 静态出版

    在发布时将页面渲染成文件,这样活页就不会承载编辑器的运行时间。

  • 自定义后端

    通过应用程序已经用来提供页面的路径存储、转换和提供输出。

  • CDN

    把已发布的资产和标记推到边缘,缓存失效由你控制。

  • 自定义部署

    从发布操作触发你现有的构建或部署流水线。

GrapesJS 负责创作。你的基础设施可以处理发布。

多租户

构建一个多租户的Angular页面构建器

只需部署一个Angular应用,一个编辑器,以及为每个客户单独的页面世界。

Angular SaaS

  • Org A

    • 页面
    • 资产
    • 模板
  • Org B

    • 页面
    • 资产
    • 模板
  • Org C

    • 页面
    • 资产
    • 模板
  • 每个租户单独处理项目,由认证用户解析,而非路由参数。
  • 租户范围的资产存储,因此上传内容永远不会出现在其他客户的资产管理器中。
  • 模板可以是全球性的、按计划或按租户的,具体取决于你销售的产品。
  • 服务器对每次加载、存储和发布调用都执行角色和权限。
  • 按租户进行品牌标识,从编辑器的铬色到区块调色板。
  • 发布目标因租户而异——他们的域名、CDN、流水线。

这些都不是GrapesJS的功能。编辑器没有租户的概念:它加载分配给它的项目并存储被交还的项目。租户是你的Angular应用和后端实现的——这也是它能匹配你已有的隔离模型的原因。

探索SaaS页面构建器
白标

让你的Angular页面构建器成为你自己的

编辑器没有任何东西必须看起来像编辑器。用户触摸的每个表面都可以配置、替换或移除。

  • 你的标志代替了编辑的镀铬装饰
  • 是你的颜色标记,不是第三方主题
  • 自定义面板,或者你自己的 Angular UI 通过命令驱动编辑器
  • 只有你的产品支持的模块
  • 这些模板来自你的设计系统
  • 你的词汇——部分、模块、布局,用户已经说的那些
  • 这些角色决定了谁可以编辑、谁可以发表、谁只能发表评论
  • 服务器强制执行的权限,反映在UI中

把可视化编辑器变成你Angular产品的原生部分。

探索白标页面构建器
积分

将GrapesJS与Angular整合

简短版,分为四个步骤。完整指南——生命周期细节、封装器、无区域变更检测、生产问题——独立于一页,且内容远不止于此。

  1. 1

    安装

    把编辑器添加到你的应用里。它是一个普通的npm包,没有Angular特定的构建步骤。

  2. 2

    创建编辑服务

    将编辑器实例放在可注入服务中,这样组件保持精简,且实例便于共享、模拟和拆解。

  3. 3

    在 ngAfterViewInit 中初始化

    容器元素必须在编辑器创建前就已在 DOM 中,因为 GrapesJS 会立即测量它。

  4. 4

    在ngOnDestroy中正确摧毁

    当路由离开时调用 destroy。没有它,编辑器会保留其 DOM 监听器,下一次导航时会泄漏实例。

npm install grapesjs

一个依赖。不需要针对Angular的专用包装。

page-builder.service.tsts
import { Injectable, NgZone, inject } from '@angular/core';
import grapesjs, { type Editor } from 'grapesjs';

@Injectable({ providedIn: 'root' })
export class PageBuilderService {
  private readonly zone = inject(NgZone);
  private editor?: Editor;

  create(container: HTMLElement): Editor {
    // GrapesJS binds its own DOM listeners to the canvas. Creating it outside
    // Angular keeps every drag frame from scheduling change detection.
    this.editor = this.zone.runOutsideAngular(() =>
      grapesjs.init({
        container,
        height: '100%',
        fromElement: false,
        storageManager: false,
      })
    );

    return this.editor;
  }

  destroy(): void {
    this.editor?.destroy();
    this.editor = undefined;
  }
}

服务拥有实例及其生命周期;组件只拥有容器。

page-builder.component.tsts
import {
  AfterViewInit,
  Component,
  ElementRef,
  OnDestroy,
  inject,
  viewChild,
} from '@angular/core';
import { PageBuilderService } from './page-builder.service';

@Component({
  selector: 'app-page-builder',
  standalone: true,
  template: '<div #canvas class="builder"></div>',
  styles: '.builder { height: 100vh; }',
})
export class PageBuilderComponent implements AfterViewInit, OnDestroy {
  private readonly builder = inject(PageBuilderService);
  private readonly canvas = viewChild.required<ElementRef<HTMLElement>>('canvas');

  ngAfterViewInit(): void {
    // The container has to be in the DOM first: GrapesJS measures it on init.
    this.builder.create(this.canvas().nativeElement);
  }

  ngOnDestroy(): void {
    // Without this the editor keeps its listeners after the route changes.
    this.builder.destroy();
  }
}

视图存在后再创建,视图消失后销毁。这对组合是大部分整合。

需要完整的Angular集成指南吗?

包装器选项、无区域变更检测、懒散加载的编辑器路线、资产处理和生产清单都在这里一贯覆盖。

阅读Angular集成指南
变化检测

使用Angular变化检测

GrapesJS 会发出自己的事件,而这些事件并非来自 Angular。协调两者只需几行,但跳过它就会产生每个集成最先出现的两个 bug。

  1. GrapesJS 活动
  2. NgZone.run()
  3. Angular 状态
  4. UI 更新
page-builder.component.tsts
editor.on('storage:end:store', () => {
  // Editor events fire outside Angular because the editor was created there.
  // Re-enter the zone before touching state the template renders.
  this.zone.run(() => this.lastSavedAt.set(new Date()));
});

在更新渲染状态的处理程序中重新进入该区域。

在runOutsideAngular内创建编辑器,这样画布交互不会在每一帧都调度变更检测,然后在少数几个实际更新模板渲染状态的事件处理程序中重新进入区域。在无区域应用中,同一批处理程序会更新信号,外部封装器就不再需要了。

更多关于Angular生命周期和区域的信息
服务器端渲染

Angular SSR 和 GrapesJS

GrapesJS 需要一个浏览器 DOM。在 Angular SSR 或 Angular 通用中,编辑器只在浏览器中创建——绕过它的路由仍会正常在服务器上渲染。

用isPlatformBrowser守护初始化,并在服务器早期返回。其余路由保持不变:守卫、解析器和周围标记保持服务器渲染的行为,只有编辑器容器是空的。

page-builder.component.tsts
import { PLATFORM_ID, inject } from '@angular/core';
import { isPlatformBrowser } from '@angular/common';

export class PageBuilderComponent implements AfterViewInit {
  private readonly isBrowser = isPlatformBrowser(inject(PLATFORM_ID));

  ngAfterViewInit(): void {
    // There is no DOM on the server and GrapesJS needs one, so the editor is
    // created in the browser only. The rest of the route still renders on the
    // server as usual.
    if (!this.isBrowser) return;
    this.builder.create(this.canvas().nativeElement);
  }
}

整个SSR调整:在编辑器创建前先做一次平台检查。

TypeScript 与《进攻的巨人》

Angular、TypeScript 与 AOT

集成是普通的Angular代码,这是值得一提的重点。

  • TypeScript友好型

    编辑器自带类型定义,因此实例、配置和事件在调用站点被类型化。

  • Angular 生命周期

    创建和拆解依赖于 ngAfterViewInit 和 ngOnDestroy——无需在组件树外手动启动。

  • 兼容AOT

    集成中没有任何内容依赖于运行时模板编译,因此编辑器路由的构建方式就像其他懒散加载的路径一样。

  • 仅浏览器初始化

    在使用 SSR 时,只有编辑器创建部分被浏览器保护;其余组件正常编译和渲染。

构建与采用

从零开始构建一个Angular页面构建器,而不是GrapesJS

以下所有功能都必须具备,视觉编辑器才可用。唯一的问题是你自己写的是哪一项。

能力从零开始GrapesJS
视觉画布需自行构建已内置
拖拽需自行构建已内置
组成部分需自行构建已内置
区块需自行构建可扩展
造型需自行构建已内置
响应式剪辑需自行构建已内置
资产需自行构建可扩展
模板需自行构建可扩展
存储需自行构建可扩展
出口需自行构建可扩展
Angular 积分需自行构建需集成

“可扩展”意味着子系统存在,并且有文档化的API指向你自己的实现——而不是它预先接线到你的后端。已在2026-09-03上与GrapesJS 0.23.6进行验证。

打造你的Angular产品。不要重建视觉编辑引擎。

  1. GrapesJS
  2. Angular integration
  3. Blocks
  4. Templates
  5. Forms
  6. Storage
  7. Assets
  8. Export
  9. Publishing

一个实际工作的构建器最终得到的堆栈。GrapesJS覆盖了第一层;剩下的由你自行组装、安装或购买。

插件

用插件扩展你的Angular页面构建器

引擎为你提供了编辑界面。在特定产品之上——块色板、模板系统、富文本、持久化、生产退出路径——这些都是 GJS.Market 插件发挥作用的地方。下面的每个列表都是真实产品,价格如图所示。

构建还是延伸

从编辑器开始。添加你的产品需求。

两列的结尾都是能用的建筑。它们在你两年后还要维护多少不同。

GrapesJS 提供可视化编辑的基础。GJS.Market 插件允许你扩展构建器,增加更多功能,而无需内部构建所有功能。

所有东西都自己动手

  • 在首个可用版本发布前,还需要进一步开发
  • 随着浏览器、Angular和设计系统的变化,维护也要更多
  • 更多只有你团队能理解的内部代码
  • 每个编辑子系统都变成了你随时待命的

用插件扩展

  1. 安装产品真正需要的东西
  2. 根据你的内容模型进行配置
  3. 自定义用户看到的部分
  4. 发货,并根据自己的预算管理
受众

谁在开发Angular页面构建器?

五种反复出现的形状,以及它们用视觉编辑器真正带来的效果。

SaaS 公司

为客户目前请求客服更改页面的产品添加可视化编辑。

代理机构

为每个客户构建定制的编辑环境,而不是把没人想要的CMS交给别人。

CMS 平台

无需花一年时间从零开始编写编辑器引擎,就能添加视觉编辑。

营销平台

让营销人员创建和更改页面,无需开发人员参与每个标题的循环。

企业队

创建受控的内部编辑工作流程,在那里可以编辑的内容和可以构建的内容同等重要。

选择你的道路

选择合适的页面构建方法

发布视觉编辑器的四种方式。它们有重叠,但起点不同——选错限制会显得晚。

在另一个框架上构建同样的东西?React、Next.js和Vue的论点是一样的——只是生命周期代码有所变化。 React 页面构建器, Next.js 页面构建器, Vue 页面构建器.

性能

性能考量

编辑器是一个繁重的应用程序,而已发布的页面则不是。把它们当作一个捆绑包来处理是值得尽早避免的错误。

  1. 懒惰加载编辑器路线

    从不打开构建器的用户绝不应该下载它。懒惰的做法会让编辑器无法进入你的主捆绑包。

  2. 避免不必要的重渲染

    在 Angular 区域外创建编辑器,并只在更新渲染状态的处理程序中重新进入。

  3. 优化大型资产库

    把资产管理工具分页对照你的API,而不是一次给它几千张图片。

  4. 只有在需要时才初始化

    创建编辑器实际显示时的实例,而不是当周围组件挂载时。

  5. 将编辑器代码排除在已发布页面之外

    发布的输出是HTML和CSS。编辑器本身不需要附带。

编辑器运行时和发布页面不需要有相同的性能要求。

安全性

安全考量

可视化编辑器接受用户创作的内容并将其写回你的系统。这些内容都应存储在该交换的服务器端。

  1. 服务器端授权

    每次加载、存储和发布调用时,检查该用户是否会对该项目采取行动。

  2. 租户隔离

    从会话中解析租户,绝不要从客户端可以更改的参数中解析。

  3. 上传验证

    验证服务器端的类型和大小,并从无法执行上传的源头提供上传。

  4. API 认证

    存储适配器运行在浏览器中。它的端点需要和你 API 其他部分相同的认证。

  5. 内容净化

    编辑者可能会嵌入自定义代码,在该标记发送给其他人之前,先在服务器上进行净化处理。

  6. 受保护的发布端点

    发布改变了公众看到的内容。限制速率,记录数据,并在自身许可下进行门禁。

  7. 服务器端权限检查

    隐藏按钮会改变UI,而不是API。UI所暗示的每一条规则都必须存在于它背后。

切勿只依赖客户端权限。

服务

需要帮助构建你的Angular页面构建器吗?

需要帮助在Angular应用中集成、扩展或定制GrapesJS吗?我们的团队可以协助集成、定制插件、UI定制和生产实现。

  • Angular 集成与编辑器架构
  • 自定义组件、模块和插件
  • UI 定制与白标
  • 存储、发布与生产推广
探索服务
FAQ

Angular 页面构建器问题

什么是Angular页面构建器?

Angular 应用中的可视化编辑器,允许用户通过将组件拖到画布上来组装页面,而无需写标记。Angular 应用拥有路由、认证和数据;编辑器拥有编辑表面。

我可以和Angular一起使用吗?

是的。GrapesJS 是框架无关的:它渲染成你给出的容器元素,所以它在 Angular 组件内工作,就像其他基于 DOM 的库一样。

GrapesJS 是 Angular 页面构建器吗?

不——它是Angular页面构建器所基于的视觉编辑引擎。没有官方的Angular封装器;你直接集成核心库,它既是一个组件,也是一个服务。

我该如何将GrapesJS与Angular整合?

安装包,将实例保留在可注入服务中,容器进入DOM后在ngAfterViewInit中创建,并在ngOnDestroy中销毁。完整指南涵盖了包装器、区域和生产相关问题。

我可以创建自定义区块吗?

是的。区块通过区块管理器注册,带有你自己的标签、类别和内容,所以调色板只能包含你产品支持的部分。

我可以创建自定义组件吗?

是的。组件类型会注册各自的traits、丢弃规则和行为,这就是编辑器从通用HTML缩减到内容模型的方式。

我可以创建可重复使用的模板吗?

是的。保存的项目可以重新加载作为新页面的起点。如果你不想构建UI,也可以作为插件使用模板库和管理器。

我可以把项目保存到我的Angular后端吗?

是的。注册一个自定义存储适配器,其加载和存储方法调用你的API到HttpClient,这样拦截器、认证头部和错误处理都能正常应用。

我可以用自己的数据库吗?

是的。编辑器生成的是JSON文档,从不直接与数据库通信,所以文档存储在哪里完全是后台决定。

我能用Angular构建一个登陆页面构建器吗?

是的,而且它是最常见的用途之一:有限的块式调色板、贴合品牌的模板,以及一个发布动作,可以写入你的营销页面所接收到的任何地方。

我能做一个Angular CMS编辑器吗?

是的。编辑器取代了基于表单的编辑界面;你的CMS保留内容类型、工作流程和权限的所有权。

我能用Angular做一个表单构建器吗?

是的。用traits注册你自己的现场组件作为组件类型进行验证和命名,这样用户组装的组件映射到后端能理解的模式上。

我可以构建一个多租户的 Angular 页面构建器吗?

是的,但租户是你应用的工作。编辑器没有租户的概念——你的后台负责解析当前用户可能看到的项目、资产和模板。

我能创建一个白标的Angular构建器吗?

是的。面板、图标、颜色、块类和术语都可以配置,你可以通过自己的 Angular UI 命令 API 驱动编辑器。

GrapesJS和Angular SSR兼容吗?

周围路由在服务器上正常渲染;编辑器本身仅在浏览器中创建。守卫初始化时使用isPlatformBrowser,并在服务器早期返回。

GrapesJS与Angular的NgZone是如何工作的?

在runOutsideAngular里创建编辑器,这样画布交互不会持续触发变更检测,然后在少数更新模板渲染状态的事件处理程序中使用NgZone.run。

我可以用TypeScript吗?

是的。GrapesJS 发布了自己的类型定义,因此编辑器实例、配置对象和事件都用普通的 Angular TypeScript 代码库类型化。

我可以用插件扩展构建器吗?

是的。插件是接收编辑器并注册组件、块、命令或面板的功能。GJS.Market 列出了免费和商业插件,用于块、富文本、存储、资源和导出。

开始

无需从零开始,即可构建你的Angular页面构建器

应用用Angular,视觉编辑用GrapesJS。添加你自己的组件、模块、模板、存储和发布流程——需要时再用GJS.Market插件扩展构建器。

开始

开始

安装编辑器,挂载到Angular组件内的容器上,下午屏幕上就有东西。

开始
延伸

浏览插件

模块、模板、富文本、存储和导出——安装产品所需的功能,而不是自己写。

浏览插件
需集成

查看Angular指南

生命周期、区域、SSR、封装器和生产检查表,在集成页面端到端都有覆盖。

查看Angular指南

你的Angular应用。你的编辑器。你的产品。