在 Vue.js 2.x 项目中使用 npm 版 CKEditor 5 富文本编辑器组件
2026/9/16 18:14:39 网站建设 项目流程

在 Vue.js 2.x 项目中使用 npm 版 CKEditor 5 富文本编辑器组件

【免费下载链接】ckeditor5Powerful rich text editor framework with a modular architecture, modern integrations, and features like collaborative editing.项目地址: https://gitcode.com/GitHub_Trending/ck/ckeditor5

CKEditor 5 官方为 Vue.js 2.x 提供了开箱即用的<ckeditor>封装组件(npm 包@ckeditor/ckeditor5-vue2),只需少量代码即可在表单、内容管理系统或任何需要富文本编辑的场景中接入一个模块化、插件驱动的编辑器。本文基于官方集成指南(vuejs-v2.md),完整讲解安装配置、组件指令与事件、Document 编辑器适配和 UI 本地化,并结合仓库源码说明底层原理,帮助你在 Vue 2 应用中快速落地一套可生产使用的编辑器方案。

注意:Vue 2 已停止维护(EOL),官方不再为其提供持续更新。如果你的项目可以升级,建议优先使用 Vue 3+ 的集成方案,参见 Vue.js 3+ 富文本编辑器组件。本指南面向仍运行在 Vue 2.x 上的存量项目。

快速开始

本指南假设你已经拥有一个可运行的 Vue 项目。接下来的步骤将完成依赖安装、全局注册和最小可用示例。

安装依赖包

首先安装 CKEditor 5 本体。官方将插件按授权模型拆分为两个包:

  • ckeditor5—— 包含开源(GPL)插件与特性。
  • ckeditor5-premium-features—— 包含商业(付费)插件与特性,例如格式刷(Format Painter)、协作编辑等。
npm install ckeditor5 ckeditor5-premium-features

根据你的插件选型和许可证类型,可能只需安装第一个包,也可能两个都需要。仓库中 packages/ckeditor5/src/index.ts 统一导出了全部开源子包(如ckeditor5-basic-stylesckeditor5-editor-classicckeditor5-table等)的插件与类,因此从ckeditor5一个包即可导入绝大多数开源能力。

随后安装 Vue 2 专用的 WYSIWYG 编辑器组件:

npm install @ckeditor/ckeditor5-vue2

在应用根文件中注册组件

要创建编辑器实例,需要先在你的应用入口文件(例如 Vue CLI 生成的main.js)中导入编辑器与组件模块,并通过Vue.use( CKEditor )将其注册为全局组件:

import Vue from 'vue'; import CKEditor from '@ckeditor/ckeditor5-vue2'; import App from './App.vue'; Vue.use( CKEditor ); new Vue( App ).$mount( '#app' );

自 CKEditor 5 44.0.0 版本起,licenseKey配置项成为使用编辑器的必要条件。如果你使用的是从 npm 自托管的编辑器,要么遵守 GPL 许可,要么为自托管分发版本获取商业许可证。可以申请免费试用密钥来评估自托管方案。

在模板中使用<ckeditor>组件

下面是一个同时使用开源插件与商业插件的完整示例。v-model负责双向绑定编辑器内容,:config传入编辑器配置,:editor指定编辑器构造器(这里使用经典编辑器ClassicEditor):

<template> <ckeditor :editor="editor" v-model="editorData" :config="editorConfig" /> </template> <script> import { ClassicEditor, Essentials, Paragraph, Bold, Italic } from 'ckeditor5'; import { FormatPainter } from 'ckeditor5-premium-features'; import 'ckeditor5/ckeditor5.css'; import 'ckeditor5-premium-features/ckeditor5-premium-features.css'; export default { name: 'app', data() { return { editor: ClassicEditor, editorData: '<p>Hello from CKEditor 5 in Vue 2!</p>', editorConfig: { licenseKey: '<YOUR_LICENSE_KEY>', plugins: [ Essentials, Paragraph, Bold, Italic, FormatPainter ], toolbar: [ 'undo', 'redo', '|', 'bold', 'italic', '|', 'formatPainter' ] } }; } }; </script>

注意上面示例同时引入了两套 CSS:

  • ckeditor5/ckeditor5.css—— 开源插件的样式;
  • ckeditor5-premium-features/ckeditor5-premium-features.css—— 商业插件的样式。

与 JavaScript 模块一样,两套样式按插件归属分别引入,避免把商业插件的样式混入纯开源构建。

仅在局部使用组件

如果不想全局注册,可以完全跳过Vue.use( CKEditor ),改用视图的components属性按需注册。此时从包中导出的是CKEditor.component

<template> <ckeditor :editor="editor" v-model="editorData" :config="editorConfig" /> </template> <script> import CKEditor from '@ckeditor/ckeditor5-vue2'; import { Bold, ClassicEditor, Essentials, Italic, Paragraph } from 'ckeditor5'; import 'ckeditor5/ckeditor5.css'; export default { name: 'app', components: { ckeditor: CKEditor.component }, data() { return { editor: ClassicEditor, editorData: '<p>Hello from CKEditor 5 in Vue 2!</p>', editorConfig: { licenseKey: '<YOUR_LICENSE_KEY>', // 或者填 'GPL' plugins: [ Bold, Essentials, Italic, Paragraph ], toolbar: [ 'undo', 'redo', '|', 'bold', 'italic' ] } }; } }; </script>

局部注册的好处是按需加载:只有渲染了<ckeditor>的视图才会创建编辑器实例,适合编辑器仅在管理后台等少数页面出现的中大型应用。

组件指令(Props)详解

@ckeditor/ckeditor5-vue2组件暴露了一组指令,用于控制编辑器类型、内容、配置与只读状态。下面逐一说明,并给出对应的底层实现依据。

editor:指定编辑器构造器

该指令指定组件要使用的编辑器类型,必须直接引用编辑器构造器(而非字符串名称):

<template> <ckeditor :editor="editor" /> </template> <script> import { ClassicEditor } from 'ckeditor5'; export default { name: 'app', data() { return { editor: ClassicEditor, // ... }; } }; </script>

ckeditor5包从 packages/ckeditor5/src/index.ts 导出ClassicEditorInlineEditorBalloonEditorDecoupledEditorMultiRootEditor等全部编辑器实现,可按应用形态自由选择。

tag-name:自定义承载元素

默认情况下,组件会创建一个<div>容器,该容器会作为元素传入编辑器(例如经典编辑器的ClassicEditor#element)。你可以通过该指令改变承载元素,例如创建<textarea>

<ckeditor :editor="editor" tag-name="textarea" />

这一能力对表单集成很有用——经典编辑器本就支持替换原生<textarea>并与表单提交流程联动。

v-model:双向数据绑定

这是 Vue 表单输入的标准指令。与下方的value不同,v-model建立的是双向绑定,它负责:

  • 设置编辑器的初始内容;
  • 在用户输入等操作改变编辑器内容时,自动同步更新应用状态;
  • 在必要时(编程式地)重新设置编辑器内容。
<template> <div> <ckeditor :editor="editor" v-model="editorData" /> <button v-on:click="emptyEditor()">Empty the editor</button> <h2>Editor data</h2> <code>{{ editorData }}</code> </div> </template> <script> import { ClassicEditor } from 'ckeditor5'; export default { name: 'app', data() { return { editor: ClassicEditor, editorData: '<p>Content of the editor.</p>' }; }, methods: { emptyEditor() { this.editorData = ''; } } }; </script>

上例中,editorData会随用户输入自动更新,也可以通过修改editorData(如emptyEditor())来清空或重置编辑器内容。若只想在数据变化时触发副作用(而不维护绑定状态),应监听input事件(见下文)。

value:单向数据绑定

value提供单向绑定,仅用于设置编辑器内容。与v-model不同,编辑器内容变化时value不会自动更新:

<template> <ckeditor :editor="editor" :value="editorData" /> </template> <script> import { ClassicEditor } from 'ckeditor5'; export default { name: 'app', data() { return { editor: ClassicEditor, editorData: '<p>Content of the editor.</p>' }; } }; </script>

需要响应内容变化时,配合input事件使用。底层来看,无论哪种绑定,最终都会落到编辑器实例的setData()/getData()方法上(见 Editor#setData 与Editor#getData()),更多数据操作细节可参考 Getting and setting data 指南。

config:编辑器配置

该指令指定编辑器的完整配置对象。配置类型对应源码中的EditorConfig接口(见 editorconfig.ts),包含pluginstoolbarlicenseKeylanguagetranslationsroot.initialDatamenuBarextraPlugins等众多选项:

<template> <ckeditor :editor="editor" :config="editorConfig" /> </template> <script> import { ClassicEditor } from 'ckeditor5'; export default { name: 'app', data() { return { editor: ClassicEditor, editorConfig: { toolbar: [ 'bold', 'italic', '|', 'link' ] } }; } }; </script>

配置对象在编辑器初始化时由Config机制存储,可通过editor.config.get( '...' )在任何插件中读取。工具栏配置的更多选项可参考 工具栏设置,完整配置项说明见 配置指南。

disabled:控制只读状态

该指令控制编辑器的isReadOnly属性,它设置编辑器的初始只读状态,并可在编辑器生命周期内动态切换:

<template> <ckeditor :editor="editor" :disabled="editorDisabled" /> </template> <script> import { ClassicEditor } from 'ckeditor5'; export default { name: 'app', data() { return { editor: ClassicEditor, // 该编辑器在创建时即为只读。 editorDisabled: true }; } }; </script>

在底层,isReadOnly由 Editor 基类提供。值得注意的是,自 34.0.0 起它已成为只读 getter,直接赋值会抛出editor-isreadonly-has-no-setter错误(见 editor.ts#L650-L673)。正确的方式是通过带锁机制的enableReadOnlyMode( lockId )/disableReadOnlyMode( lockId )方法切换:每个功能用唯一 ID 上锁,只有所有锁都被释放后编辑器才恢复可编辑(见 enableReadOnlyMode 与 disableReadOnlyMode)。Vue 组件层的disabled指令正是对这套只读状态机制的高层封装。

组件事件(Events)详解

组件将编辑器实例的核心生命周期与交互事件以 Vue 事件的形式对外暴露,便于在特定时机执行自己的逻辑。

组件事件对应的编辑器事件触发时机
readyEditor#ready编辑器的数据与所有组件就绪后
focusViewDocument#focus编辑器获得焦点时
blurViewDocument#blur编辑器失去焦点时
inputModelDocument#change:data文档数据发生变化时
destroyEditor#destroy编辑器实例被销毁时

ready

对应编辑器的ready事件。该事件在数据与所有附加编辑器组件就绪后触发,事件定义见 EditorReadyEvent。它也是下文 Document 编辑器手动挂载工具栏的推荐时机:

<ckeditor :editor="editor" @ready="onEditorReady" />

focusblur

分别对应视图层文档(ViewDocument)的focusblur事件。这两个事件由引擎的焦点观察器(FocusObserver,见 focusobserver.ts)负责监听与分发,常用于实现自动保存、联动校验或 UI 状态切换:

<ckeditor :editor="editor" @focus="onEditorFocus" /> <ckeditor :editor="editor" @blur="onEditorBlur" />

input

对应模型层文档的change:data事件,即文档数据发生变化(例如用户输入)时触发。这也是v-model指令内部所依赖的核心事件:

<ckeditor :editor="editor" @input="onEditorInput" />

destroy

对应编辑器的destroy事件,事件定义见 EditorDestroyEvent,通常用于插件清理或埋点上报:

<ckeditor :editor="editor" @destroy="onEditorDestroy" />

注意:编辑器的销毁过程是基于 Promise 的,因此destroy事件可能在实际 Promise 完成之前触发,不要在事件回调中假定 DOM 已经清理完毕。

常见集成场景

使用 Document(解耦)编辑器

如果你使用 Document(解耦)编辑器类型,需要手动将编辑器工具栏插入到 DOM 中——工具栏不会像经典编辑器那样自动渲染。由于工具栏在编辑器实例ready之前无法访问,应当把工具栏插入代码放在组件ready事件回调中执行:

<template> <ckeditor :editor="editor" @ready="onReady" /> </template> <script> import { DecoupledEditor, Bold, Essentials, Italic, Paragraph } from 'ckeditor5'; import 'ckeditor5/ckeditor5.css' export default { name: 'app', data() { return { editor: DecoupledEditor, // ... }; }, methods: { onReady( editor ) { // 将工具栏插入到可编辑区域之前。 editor.ui.getEditableElement().parentElement.insertBefore( editor.ui.view.toolbar.element, editor.ui.getEditableElement() ); } } }; </script>

关键点在于editor.ui.view.toolbar.element只有在ready之后才存在。解耦编辑器在仓库中位于 packages/ckeditor5-editor-decoupled/src/decouplededitor.ts,其create()方法与 UI 视图将"编辑区"与"工具栏"分离设计,因此需要集成方决定工具栏的 DOM 归属。编辑器类型总览可参考 编辑器类型 与 框架文档。

本地化(UI 语言)

CKEditor 5 支持多种 UI 语言,官方 Vue 2 组件同样支持。与 CSS 样式表类似,开源与商业两个包各自携带独立的翻译文件,需要分别导入后放入editorConfigtranslations数组中:

<template> <ckeditor :editor="editor" v-model="editorData" :config="editorConfig" /> </template> <script> import { ClassicEditor, Bold, Essentials, Italic, Paragraph } from 'ckeditor5'; // 更多导入…… import coreTranslations from 'ckeditor5/translations/es.js'; import premiumFeaturesTranslations from 'ckeditor5-premium-features/translations/es.js'; export default { name: 'app', data() { return { editor: ClassicEditor, editorData: '<p>Hola desde CKEditor 5 en Vue 2!</p>', editorConfig: { // ……其他配置项…… translations: [ coreTranslations, premiumFeaturesTranslations ] } }; } }; </script>

将语言切换为中文时,把es.js换成zh-cn.js(或zh.js,以对应语言文件实际命名为准)即可。翻译条目通过编辑器配置中的translations选项合并进本地化系统;此外,language配置项还支持为 UI 与内容分别指定语言(如language: { ui: 'en', content: 'ar' }),详见 UI 语言设置指南。

下一步

  • 学习如何用editor.getData()/editor.setData()精细操作编辑器数据:获取与设置数据。
  • 进一步自定义编辑器:完整的配置项体系见配置指南。
  • 探索具体功能插件的用法与配置:功能特性总览。

组件的源码在 GitHub 上独立维护(ckeditor/ckeditor5-vue2仓库),如在使用中发现问题,可在该仓库提交 issue。需要注意的是,官方推荐新项目直接采用 Vue 3+ 集成(vue-default-npm.md),Vue 2 方案仅面向既有代码库的维护与升级过渡。

【免费下载链接】ckeditor5Powerful rich text editor framework with a modular architecture, modern integrations, and features like collaborative editing.项目地址: https://gitcode.com/GitHub_Trending/ck/ckeditor5

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询