Angular结合quill实现富文本编辑器
1. 前言
由于需要一个富文本编辑器来编辑一些网页内容, 手动编辑后存储到数据库比较麻烦, 所以着手实现一个自己的富文本编辑器, 来编辑和存储一些 html 文件.
这里使用 Angular 框架, 加 Quill 库实现.
ngx-quill: https://github.com/KillerCodeMonkey/ngx-quill
quill 官网: https://quilljs.com/
2. 创建 Angular 工程
2.1. 创建工程
首先创建一个 angular 工程. 工程的名字就叫 angular-editor.
1 |
|
2.2. 添加依赖
这里需要添加 ngx-quill 依赖包, 以下是 ngx-quill 与 Angular 之间的兼容关系.
Angular | ngx-quill | supported |
---|---|---|
v15 | >= 20.0.0 | until May, 2024 |
v14 | >= 17.0.0 | until Dec 02, 2023 |
v13 | >= 15.0.0, < 17.0.0 | until May 04, 2023 |
由于我目前使用的 angular 版本 13.3.11, 我选择了一个稳定版本ngx-quill@16.2.1
查看ngx-quill@16.2.1的配置文件package.json, 其对应的 quill 版本为quill@1.3.7, 所以这里 quill 使用quill@1.3.7. 为了让 typescript 能识别类型信息, 这里还需要导入一个开发依赖包@types/quill@1.3.10, 版本也可以从 ngx-quill 的 package.json 中找到.
1 |
|
当前最新版本为 ngx-quill@20.0.1 quill@1.3.7
3. 创建编辑器
3.1. 引入 Quill 模块
添加依赖包之后还不能直接使用 Quill, 还需要再使用 Quill 的 Module 声明文件引入它.
以下以根模块为例讲解如何引入模块,引入 ngx-quill 的 QuillModule
app.module.ts
1 | import { NgModule } from "@angular/core"; |
3.2. 引入 quill css 样式
由于我使用的 scss, 所以可以很方便的引入 quill css. 可以在预编译的时候将 quill 的样式编译进来.
找到 styles.scss, 添加如下代码引入 quill 样式
quill 提供两种主题, 一种是 bubble, 另一种是 snow, 默认是 snow, 可以任选一种导入, 也可以同时导入两种主题, 方便动态切换样式.
styles.scss
1 | @import url("https://cdn.quilljs.com/1.3.7/quill.snow.css"); |
3.3. 将 quill 富文本编辑器添加到页面
做好以上准备工作, 我们就可以将 quill 富文本编辑器. 以 app.component.html 为例, 只要在页面添加这样一行, 然后启动 angular 应用, 就可以看到编辑器了.
1 | <quill-editor></quill-editor> |
启动应用看效果
1 | ng serve --open |
4. 加载与获取富文本内容
当我们使用 quill 编辑文档的时候, 往往不是从空白文档开始, 大多数情况下我们是在已有文档的基础上进行修改.
当我们拿到一个文档时, 如何将其内容加载到 quill 编辑器中呢? 网上很多的教程或博客讲解得不够深入.
首先要将 quill-editor 与一个 control 控件连接起来, 如下:
1 | <form [formGroup]="form"> |
当然连接之前, 我们需要创建该控件.
1 | form: FormGroup = this.fb.group({ |
这样我们通过控制该控件, 可以在构建 FormControl 时传入, 也可以在创建完 FormControl 后通过 setValue 方法加载 html 内容, 就能加载 html 内容到 quill 编辑器中. 而在 quill 中编辑文档内容时, control 控件中的内容会自动更新.
当我们准备存盘时, 获取到该控件, 通过 value 熟悉即可获取到修改后的 html 内容 form.get(‘html’).value, 而不必去操作 quill-editor 组件.
更多用法可以参考ngx-quill 示例
5. 如何处理插入图片
当插入图片时, quill 默认会将图片转换成 base64 编码嵌入到文本中, 因为我需要将富文本存储到数据库中, 这种默认方式会导致数据库字段内容庞大.
影响查询性能. 所以我想将这种默认行为改为, 将图片保存到图片服务器, 在富文本中仅仅插入图片链接.
首先需要捕获 onEditorCreated 事件, 捕获该事件后我们才有机会替换 quill 编辑器的默认行为. 获取该事件的方法十分简单.
只需要给 qull-editor 绑定一个定制的方法editorCreated($event)
, 通过$event 即可获取到创建好的 editor 本身.
1 | <quill-editor |
捕获到 onEditorCreated 事件以及获取到 editor 后我们就可以客制化插入图片的行为了.
1 | /** |
将 image handler 替换为自己的 imageHander. 例如, 一下是我实现的一个 imageHandler.
实现方式比较容易理解, 即将图片上传到文件服务器, 然后获取到图片的 url, 将 url 嵌入到图片插入位置.
这里 imageHandler 做的事情很简单, 只是出发一个 open dialog 事件.
为什么这样设计? 因为在 imageHandler 内部调用 this.dialog.open 创建的 DialogOverviewExampleDialog 脱离了 NgZone, 后续无论是渲染, 还是关闭对话框都会出现很奇怪的行为.
所以在 imageHandler 内部只是触发一个事件.外部的 component 接收到这个事件再打开对话框.
1 | /** |
外部的组件也就是 AppComponent 接收到事件再弹出对话框
1 | "window:open dialog") ( |
这里要自己设计对话框组件 DialogOverviewExampleDialog, 关闭时传出图片的 URL;
可以参照如下代码
example-dialog.component.ts
1 | import { Component, NgZone, OnInit } from "@angular/core"; |
example-dialog.component.html
1 | <div cdkDrag cdkDragRootElement=".cdk-overlay-pane" class="w-100"> |
6. 实现后的效果
实现后的效果如下:
7. Angular 系列文章
最新更新以及更多 Angular 相关文章请访问 Angular 合集 | 鹏叔的技术博客
8. 参考文档
Angular结合quill实现富文本编辑器