Vue.js 3+ 富文本编辑器组件
Vue.js 是一个用于构建 Web 用户界面的通用框架。CKEditor 5 提供了您可以应用程序中使用的官方 Vue 组件。
CKEditor 5 构建器
在我们的交互式构建器中,您可以快速体验 CKEditor 5。它提供了一个易于使用的用户界面,可帮助您配置、预览和下载适合您需求的编辑器。您可以轻松选择
- 编辑器类型。
- 您需要的功能。
- 首选框架(React、Angular、Vue 或 Vanilla JS)。
- 首选分发方式。
最后,您将获得适合您需求的现成代码!
# 快速入门
# 设置项目
本指南假定您已经拥有一个 Vue 项目。如果您没有,请查看 Vue 文档 了解如何创建它。
# 安装
首先安装以下软件包
-
ckeditor5
- 包含 CKEditor 5 的所有开源插件和功能。npm install ckeditor5
-
ckeditor5-premium-features
- 包含 CKEditor 5 的高级插件和功能。根据您的配置和所选插件,您可能不需要它。npm install ckeditor5-premium-features
-
@ckeditor/ckeditor5-vue
- CKEditor 5 用于 Vue 的 WYSIWYG 编辑器组件。npm install @ckeditor/ckeditor5-vue
安装完这些软件包后,您现在需要选择是全局安装还是本地安装 <ckeditor>
组件,并按照以下相应说明操作。
# 全局安装 <ckeditor>
组件
要全局注册 <ckeditor>
组件,您必须安装 CKEditor 5 的 Vue 插件。
如果您使用的是一个简单的 Vue 项目,您应该找到调用 createApp
函数的文件,并使用 use()
方法 注册 CkeditorPlugin
插件。
import { createApp } from 'vue';
import { CkeditorPlugin } from '@ckeditor/ckeditor5-vue';
import App from './App.vue';
createApp( App )
.use( CkeditorPlugin )
.mount( '#app' );
如果您使用的是 Nuxt.js,您可以按照 Nuxt.js 文档 获取 use()
方法并注册此插件。
现在,您可以在任何 Vue 组件中使用 <ckeditor>
组件。以下示例显示了一个具有开源和高级插件的单文件组件。
<template>
<div id="app">
<ckeditor
v-model="editorData"
:editor="editor"
:config="editorConfig"
/>
</div>
</template>
<script>
import { ClassicEditor, Bold, Essentials, Italic, Mention, Paragraph, Undo } from 'ckeditor5';
import { SlashCommand } 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!</p>',
editorConfig: {
plugins: [ Bold, Essentials, Italic, Mention, Paragraph, SlashCommand, Undo ],
toolbar: [ 'undo', 'redo', '|', 'bold', 'italic' ],
licenseKey: '<YOUR_LICENSE_KEY>',
// Other configuration options...
}
};
}
};
</script>
# 在本地使用 <ckeditor>
组件
如果您不想全局启用 CKEditor 5 组件,您可以直接从 @ckeditor/ckeditor5-vue
包中导入 Ckeditor
组件到您想要使用它的 Vue 组件中,并将它添加到 components
对象中。
<template>
<div id="app">
<ckeditor
v-model="editorData"
:editor="editor"
:config="editorConfig"
/>
</div>
</template>
<script>
import { ClassicEditor, Bold, Essentials, Italic, Mention, Paragraph, Undo } from 'ckeditor5';
import { SlashCommand } from 'ckeditor5-premium-features';
import { Ckeditor } from '@ckeditor/ckeditor5-vue';
import 'ckeditor5/ckeditor5.css';
import 'ckeditor5-premium-features/ckeditor5-premium-features.css';
export default {
name: 'app',
components: {
Ckeditor
},
data() {
return {
editor: ClassicEditor,
editorData: '<p>Hello from CKEditor 5 in Vue!</p>',
editorConfig: {
plugins: [ Bold, Essentials, Italic, Mention, Paragraph, SlashCommand, Undo ],
toolbar: [ 'undo', 'redo', '|', 'bold', 'italic' ],
licenseKey: '<YOUR_LICENSE_KEY>',
// Other configuration options...
}
};
}
};
</script>
# 组件指令
# editor
此指令指定要由组件使用的编辑器。它必须直接引用要在模板中使用的编辑器构造函数。
<template>
<div id="app">
<ckeditor :editor="editor" />
</div>
</template>
<script>
import { ClassicEditor } from 'ckeditor5';
export default {
name: 'app',
data() {
return {
editor: ClassicEditor,
// ...
};
}
};
</script>
# tag-name
默认情况下,编辑器组件会创建一个 <div>
容器,该容器用作传递给编辑器的元素(例如,ClassicEditor#element
)。可以配置该元素,例如,要创建一个 <textarea>
,请使用以下指令
<ckeditor :editor="editor" tag-name="textarea" />
# v-model
Vue 中用于表单输入的 标准指令。与 model-value
不同,它创建了一个双向数据绑定,它
- 设置初始编辑器内容。
- 当编辑器内容发生变化时(例如,用户键入时)自动更新应用程序状态。
- 可用于在必要时设置编辑器内容。
<template>
<div id="app">
<ckeditor :editor="editor" v-model="editorData" />
<button @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
属性将在用户键入和内容发生变化时自动更新。它还可用于更改(如 emptyEditor()
中)或设置编辑器的初始内容。
如果您只想在编辑器数据发生变化时执行操作,请使用 input
事件。
# model-value
允许单向数据绑定,该绑定设置编辑器的内容。与 v-model
不同,当编辑器的内容发生变化时,该值不会更新。
<template>
<div id="app">
<ckeditor :editor="editor" :model-value="editorData" />
</div>
</template>
<script>
import { ClassicEditor } from 'ckeditor5';
export default {
name: 'app',
data() {
return {
editor: ClassicEditor,
editorData: '<p>Content of the editor.</p>'
};
}
};
</script>
要执行编辑器数据发生变化时的操作,请使用 input
事件。
# config
指定编辑器的 配置。
<template>
<div id="app">
<ckeditor :editor="editor" :config="editorConfig" />
</div>
</template>
<script>
import { ClassicEditor } from 'ckeditor5';
export default {
name: 'app',
data() {
return {
editor: ClassicEditor,
editorConfig: {
toolbar: [ 'bold', 'italic', '|', 'link' ]
}
};
}
};
</script>
# disabled
此指令控制编辑器的 isReadOnly
属性。
它设置编辑器的初始只读状态,并在其生命周期中进行更改。
<template>
<div id="app">
<ckeditor :editor="editor" :disabled="editorDisabled" />
</div>
</template>
<script>
import { ClassicEditor } from 'ckeditor5';
export default {
name: 'app',
data() {
return {
editor: ClassicEditor,
// This editor will be read–only when created.
editorDisabled: true
};
}
};
</script>
# disableTwoWayDataBinding
允许禁用双向数据绑定机制。默认值为 false
。
引入此选项的原因是大文档中的性能问题。启用此标志后,v-model
指令将不再在编辑器数据发生变化时更新连接的值。
此选项允许集成者禁用默认行为,并且仅在需要时调用 editor.getData()
方法,从而防止速度变慢。您可以在 相关问题 中了解更多信息。
<ckeditor :editor="editor" :disableTwoWayDataBinding="true" />
# 组件事件
# ready
对应于 ready
编辑器事件。
<ckeditor :editor="editor" @ready="onEditorReady" />
# focus
对应于 focus
编辑器事件。
<ckeditor :editor="editor" @focus="onEditorFocus" />
# blur
对应于 blur
编辑器事件。
<ckeditor :editor="editor" @blur="onEditorBlur" />
# input
对应于 change:data
编辑器事件。
<ckeditor :editor="editor" @input="onEditorInput" />
# destroy
对应于 destroy
编辑器事件。
注意:由于编辑器的销毁是基于承诺的,因此此事件可能在实际承诺解决之前触发。
<ckeditor :editor="editor" @destroy="onEditorDestroy" />
# 如何?
# 使用 Document 编辑器类型
如果您在应用程序中使用 Document(分离)编辑器,则需要 手动将编辑器工具栏添加到 DOM 中。
由于在编辑器实例 准备好之前无法访问编辑器工具栏,因此请将工具栏插入代码放在组件的 ready
事件触发时执行的方法中,如以下示例所示
<template>
<div id="app">
<ckeditor :editor="editor" @ready="onReady" />
</div>
</template>
<script>
import { DecoupledEditor, Bold, Essentials, Italic, Paragraph, Undo } from 'ckeditor5';
import CKEditor from '@ckeditor/ckeditor5-vue';
import 'ckeditor5/ckeditor5.css';
export default {
name: 'app',
data() {
return {
editor: DecoupledEditor,
// ...
};
},
methods: {
onReady( editor ) {
// Insert the toolbar before the editable area.
editor.ui.getEditableElement().parentElement.insertBefore(
editor.ui.view.toolbar.element,
editor.ui.getEditableElement()
);
}
}
};
</script>
# 使用与协作插件的编辑器
我们提供了一个**现成的集成**,它在 Vue 应用程序中具有协作编辑功能
它不是必须在上述示例的基础上构建应用程序,但它应该可以帮助您入门。
# 本地化
CKEditor 5 支持 多种 UI 语言,官方 Vue 组件也一样。按照以下说明在您的 Vue 应用程序中翻译 CKEditor 5。
与 CSS 样式表类似,这两个软件包都有单独的翻译。按照以下示例导入它们。然后,将它们传递给组件中 editorConfig
属性内的 translations
数组
<template>
<div id="app">
<ckeditor :editor="editor" v-model="editorData" :config="editorConfig" />
</div>
</template>
<script>
import { ClassicEditor, Bold, Essentials, Italic, Paragraph } from 'ckeditor5';
// More imports...
import coreTranslations from 'ckeditor5/translations/es.js';
import premiumFeaturesTranslations from 'ckeditor5-premium-features/translations/es.js';
// Style sheets imports...
export default {
name: 'app',
data() {
return {
editor: ClassicEditor,
editorData: '<p>Hola desde CKEditor 5 en Vue!</p>',
editorConfig: {
toolbar: {
items: [ 'undo', 'redo', '|', 'bold', 'italic' ],
},
plugins: [ Bold, Essentials, Italic, Paragraph ],
translations: [ coreTranslations, premiumFeaturesTranslations ]
}
};
}
};
</script>
有关更多信息,请参阅 设置 UI 语言 指南。
# Jest 测试
您可以在 Vue 应用程序中使用 Jest 作为测试运行器。不幸的是,Jest 不会使用真正的浏览器。相反,它会在 Node.js 中运行测试,该测试使用 JSDOM。JSDOM 不是完整的 DOM 实现,虽然它足以用于标准应用程序,但它无法模拟 CKEditor 5 所需的所有 DOM API。
为了测试 CKEditor 5,建议使用利用真实浏览器并提供完整 DOM 实现的测试框架。一些流行的选择包括
这些框架为测试 CKEditor 5 提供了更好的支持,并更准确地反映了编辑器在真实浏览器环境中的行为。
如果无法做到这一点,并且仍然想要使用 Jest,则可以模拟一些必需的 API。以下是模拟 CKEditor 5 使用的一些 API 的示例
beforeAll( () => {
window.scrollTo = jest.fn();
window.ResizeObserver = class ResizeObserver {
observe() {}
unobserve() {}
disconnect() {}
};
for (const key of ['InputEvent', 'KeyboardEvent']) {
window[key].prototype.getTargetRanges = () => {
const range = new StaticRange({
startContainer: document.body.querySelector('.ck-editor__editable p')!,
startOffset: 0,
endContainer: document.body.querySelector('.ck-editor__editable p')!,
endOffset: 0,
});
return [range];
};
}
Range.prototype.getClientRects = () => ({
item: () => null,
length: 0,
[Symbol.iterator]: function* () {},
});
} );
这些模拟应该放在使用 CKEditor 5 的测试之前。它们并不完美,可能无法涵盖所有情况,但它们应该足以用于基本初始化和渲染编辑器。请记住,它们不能替代适当的浏览器测试。
# 贡献与报告问题
该组件的源代码在 GitHub 上的 https://github.com/ckeditor/ckeditor5-vue 中可用。
我们每天都在努力保持文档的完整性。您是否发现过时信息?是否缺少某些内容?请通过我们的 问题追踪器 报告。
随着 42.0.0 版本的发布,我们重新编写了许多文档以反映新的导入路径和功能。我们感谢您的反馈,帮助我们确保文档的准确性和完整性。