vue中使用ckeditor
vue中使用ckeditor很多项目中都需要使用富文本编辑器,市面上关于富文本编辑器的js库也有很多。个人使用过wangEditor,TinyMce以及ckeditor。各有各的优缺点,就不一一论述。此文单独讲述ckeditor的使用方式,包括ckeditor4以及ckeditor5搭配vue的使用方法以及如何自定义一些功能。ckeditor5ckeditor5提供了所见即所得的各种编辑解决方案。
vue中使用ckeditor
很多项目中都需要使用富文本编辑器,市面上关于富文本编辑器的js库也有很多。个人使用过wangEditor,TinyMce以及ckeditor。各有各的优缺点,就不一一论述。此文单独讲述ckeditor的使用方式,包括ckeditor4以及ckeditor5搭配vue的使用方法以及如何自定义一些功能。
ckeditor5
ckeditor5提供了所见即所得的各种编辑解决方案。从类似于googledocs和Medium的编辑器,到Slack或类似Twitter的应用程序,所有这些都可以在一个编辑框架内实现。
ckeditor有多种模式可以选择:Classic
, Balloon
,Ballon Block
, Inline
,Document
, Pagination
,可以根据自己需求下载安装各自模式。详情文档自行参考官方文档
因为Document本身自带可以编辑的东西更多,此处以Document为例:
下载安装
npm install --save @ckeditor/ckeditor5-build-decoupled-document
自定义图片上传
我们需要自定义一个图片上传的适配器,参照官方文档,完整的上传图片适配器代码如下:
uploadAdapter.js
import axios from 'axios'
export default class UploadAdapter {
constructor(loader) {
this.loader = loader
}
upload() {
return this.loader.file.then(file => new Promise((resolve, reject) => {
const data = new FormData()
data.append('file', file)
axios.request({
url: `/services/businessservice/api/attachments/uploadFile`,// 上传文件的接口地址,实际请填写完整地址
method: 'post',
data,
headers: {
'Content-Type': 'multipart/form-data'
}
}).then(res => {
console.log(res)
if (res.data.meta.code === 200) {
const url = res.data.url // 后台返回的上传成功后的图片地址
resolve({
default: url
})
}
}).catch(error => {
reject(error)
})
}))
}
abort() {
}
}
完整功能代码实现
为了让富文本编辑器看上去更像word,可以自定义设置一些样式,可以根据自己需求增加或者删除一些toolbar工具栏以及设置自己需要的语言,完整代码如下,图片上传需要引入上面自定义的图片上传的适配器
<template>
<div class="rich-container">
<div class="rich-editor document-editor">
<div id="toolbar-container" class="document-editor__toolbar" />
<div class="document-editor__editable-container">
<div id="editor" class="document-editor__editable" />
</div>
</div>
</div>
</template>
<script>
import DecoupledEditor from '@ckeditor/ckeditor5-build-decoupled-document'
import '@ckeditor/ckeditor5-build-decoupled-document/build/translations/zh-cn' // 中文包
import UploadAdapter from './uploadAdapter.js'
export default {
data() {
return {
editor: null // 编辑器实例
}
},
mounted() {
this.initCKEditor()
},
methods: {
initCKEditor() {
// 初始化编辑器
DecoupledEditor.create(document.querySelector('#editor'), {
language: 'zh-cn', // 中文
removePlugins: ['MediaEmbed'] // 除去视频按钮
}).then(editor => {
editor.plugins.get('FileRepository').createUploadAdapter = (loader) => {
return new UploadAdapter(loader)
}
const toolbarContainer = document.querySelector('#toolbar-container')
toolbarContainer.appendChild(editor.ui.view.toolbar.element)
this.editor = editor // 将编辑器保存起来,用来随时获取编辑器中的内容等,执行一些操作
}).catch(error => {
console.error(error)
})
}
}
}
</script>
<style lang="scss">
.rich-editor {
width: 60%;
min-height: 500px;
margin: 20px auto;
}
</style>
<style lang="css">
.document-editor {
border: 1px solid var(--ck-color-base-border);
border-radius: var(--ck-border-radius);
/* Set vertical boundaries for the document editor. */
max-height: 700px;
/* This element is a flex container for easier rendering. */
display: flex;
flex-flow: column nowrap;
}
.document-editor__toolbar {
/* Make sure the toolbar container is always above the editable. */
z-index: 1;
/* Create the illusion of the toolbar floating over the editable. */
box-shadow: 0 0 5px hsla( 0,0%,0%,.2 );
/* Use the CKEditor CSS variables to keep the UI consistent. */
border-bottom: 1px solid var(--ck-color-toolbar-border);
}
/* Adjust the look of the toolbar inside of the container. */
.document-editor__toolbar .ck-toolbar {
border: 0;
border-radius: 0;
}
/* Make the editable container look like the inside of a native word processor app. */
.document-editor__editable-container {
padding: calc( 2 * var(--ck-spacing-large) );
background: var(--ck-color-base-foreground);
/* Make it possible to scroll the "page" of the edited content. */
overflow-y: scroll;
}
.document-editor__editable-container .document-editor__editable.ck-editor__editable {
/* Set the dimensions of the "page". */
width: 15.8cm;
min-height: 21cm;
/* Keep the "page" off the boundaries of the container. */
padding: 1cm 2cm 2cm;
border: 1px hsl( 0,0%,82.7% ) solid;
border-radius: var(--ck-border-radius);
background: white;
/* The "page" should cast a slight shadow (3D illusion). */
box-shadow: 0 0 5px hsla( 0,0%,0%,.1 );
/* Center the "page". */
margin: 0 auto;
}
/* Override the page's width in the "Examples" section which is wider. */
.main__content-wide .document-editor__editable-container .document-editor__editable.ck-editor__editable {
width: 18cm;
}
/* Set the default font for the "page" of the content. */
.document-editor .ck-content,
.document-editor .ck-heading-dropdown .ck-list .ck-button__label {
font: 16px/1.6 "Helvetica Neue", Helvetica, Arial, sans-serif;
}
/* Adjust the headings dropdown to host some larger heading styles. */
.document-editor .ck-heading-dropdown .ck-list .ck-button__label {
line-height: calc( 1.7 * var(--ck-line-height-base) * var(--ck-font-size-base) );
min-width: 6em;
}
/* Scale down all heading previews because they are way too big to be presented in the UI.
Preserve the relative scale, though. */
.document-editor .ck-heading-dropdown .ck-list .ck-heading_heading1 .ck-button__label,
.document-editor .ck-heading-dropdown .ck-list .ck-heading_heading2 .ck-button__label {
transform: scale(0.8);
transform-origin: left;
}
/* Set the styles for "Heading 1". */
.document-editor .ck-content h2,
.document-editor .ck-heading-dropdown .ck-heading_heading1 .ck-button__label {
font-size: 2.18em;
font-weight: normal;
}
.document-editor .ck-content h2 {
line-height: 1.37em;
padding-top: .342em;
margin-bottom: .142em;
}
/* Set the styles for "Heading 2". */
.document-editor .ck-content h3,
.document-editor .ck-heading-dropdown .ck-heading_heading2 .ck-button__label {
font-size: 1.75em;
font-weight: normal;
color: hsl( 203, 100%, 50% );
}
.document-editor .ck-heading-dropdown .ck-heading_heading2.ck-on .ck-button__label {
color: var(--ck-color-list-button-on-text);
}
/* Set the styles for "Heading 2". */
.document-editor .ck-content h3 {
line-height: 1.86em;
padding-top: .171em;
margin-bottom: .357em;
}
/* Set the styles for "Heading 3". */
.document-editor .ck-content h4,
.document-editor .ck-heading-dropdown .ck-heading_heading3 .ck-button__label {
font-size: 1.31em;
font-weight: bold;
}
.document-editor .ck-content h4 {
line-height: 1.24em;
padding-top: .286em;
margin-bottom: .952em;
}
/* Make the block quoted text serif with some additional spacing. */
.document-editor .ck-content blockquote {
font-family: Georgia, serif;
margin-left: calc( 2 * var(--ck-spacing-large) );
margin-right: calc( 2 * var(--ck-spacing-large) );
}
@media only screen and (max-width: 960px) {
/* Because on mobile 2cm paddings are to big. */
.document-editor__editable-container .document-editor__editable.ck-editor__editable {
padding: 1.5em;
}
}
@media only screen and (max-width: 1200px) {
.main__content-wide .document-editor__editable-container .document-editor__editable.ck-editor__editable {
width: 100%;
}
}
/* Style document editor a'ka Google Docs.*/
@media only screen and (min-width: 1360px) {
.main .main__content.main__content-wide {
padding-right: 0;
}
}
@media only screen and (min-width: 1600px) {
.main .main__content.main__content-wide {
width: 24cm;
}
.main .main__content.main__content-wide .main__content-inner {
width: auto;
margin: 0 50px;
}
/* Keep "page" look based on viewport width. */
.main__content-wide .document-editor__editable-container .document-editor__editable.ck-editor__editable {
width: 60%;
}
}
</style>
以上就是如何在vue中使用ckeditor5的方法,当然官方也有专门针对vue和react的ckeditor组件,你可以直接拿来使用。ckeditor5-react,ckeditor5-vue,ckeditor5-angular。
效果图如下
ckeditor4
ckeditor4也有多种模式,为什么这里还需要讲ckeditor4呢,因为上面的ckeditor5更符合现代的web工程,但是却有一些功能暂时还没有解决,比如复制word文档图文,图片有的无法上传,还有一个就是对于wps文档的复制目前是有问题的,此时通过降级可以避免大多数问题。具体使用就直接自行查看官方文档。当然ckeditor4也有专门针对三大框架的版本ckeditor4-react, ckeditor4-vue,ckeditor4-angular 使用方式就不论述了,为什么不直接使用这些呢,是为了更容易的添加插件,更好的自定义自己的富文本编辑器。
下载
你可以在官网找到下载页面,下载地址
官网有多种版本下载Basic Package
,Standard Package
,Full Package
,Customize
。自行根据现需要下载相应的版本。
vue中使用ckeditor4
在我们下载的ckeditor4完整文件中,我们打开toolbarconfigurator页面可以可视化配置toolbar的显示,可以增加删除调整顺序等,然后可以获取配置,把配置复制下来保存到之前下载的config文件中。
-
将下载的ckeditor整个文件夹放在项目的public目录下
-
在public的index.html文件中引入相应的文件
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"> <link rel="icon" href="<%= BASE_URL %>favicon.ico"> <title><%= webpackConfig.name %></title> <script src="<%= BASE_URL %>ckeditor/ckeditor.js"></script> </head> <body> <noscript> <strong>We're sorry but <%= webpackConfig.name %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong> </noscript> <div id="app"></div> <!-- built files will be auto injected --> </body> </html>
- 自定义上传图片,我们可以在
fileUploadRequest
事件出发的时候自定义上传方法,可以在fileUploadResponse
上传成功后自定义上传成功的方法
完整代码
<template> <div class="rich-container"> <div class="rich-editor document-editor"> <textarea id="editor" /> </div> <el-button type="primary" size="mini" @click="getContent">获取内容</el-button> </div> </template> <script> export default { name: 'Dashboard', data() { return { editor: null } }, mounted() { this.initEditor() }, methods: { initEditor() { this.editor = window.CKEDITOR.replace('editor', { height: 600, bodyClass: 'document-editor' }) window.CKEDITOR.on('instanceReady', e => { console.log('ckeditor初始化', e) const upload = e.editor.uploadRepository upload.on('instanceCreated', function(eve) { console.log('创建了') }) e.editor.on('change', function(change) { console.log('change', change) }) e.editor.on('fileUploadRequest', (evt) => { const fileLoader = evt.data.fileLoader const formData = new FormData() const xhr = fileLoader.xhr fileLoader.uploadUrl = '/services/businessservice/api/attachments/uploadFile' // 上传文件接口地址 xhr.open('post', fileLoader.uploadUrl, true) formData.append('file', fileLoader.file, fileLoader.fileName) fileLoader.xhr.send(formData) // Prevented the default behavior. evt.stop() // 上传 }) e.editor.on('fileUploadResponse', (evt) => { evt.stop() const data = evt.data const xhr = data.fileLoader.xhr const response = xhr.responseText const res = JSON.parse(response) if (res.meta.code === 200) { data.message = res.meta.message data.url = res.data.url // 上传图片成功后返回的图片路径 } }) }) }, getContent() { console.log(this.editor.getData()) } } } </script> <style lang="scss" scoped> .rich-editor { width: 60%; min-height: 500px; margin: 20px auto; } </style>
效果图如下:
- 自定义上传图片,我们可以在
使用ckeditor4解决了二word图文复制以及wps文档的复制问题,不过还有一个问题没有解决,就是wps中的图片复制问题。
关于获取富文本编辑器内容,以及设置内容的方法ckeditor4和ckeditor5都是一样的,先获取editor实例然后调用其方法
-
获取编辑器内容:
getData()
-
获取编辑器内容:
setData()
更多推荐
所有评论(0)