ckeditor5中有几种图片上传的方式,最方便的就是简单上传,前端只用调用一个后端的方法,就可以完成上传,但问题是后端要实现这个方法。
为了避免和后端打交道,可以使用自定义上传方法的方式,把上传的图片直接传到oss上。
因为它这个官网上的教程当时我看的时候实在是懵逼,再加上很多中国的程序员也实在赶时间,所以还是写篇中文的文章来说一下,需要看官网教程的同学移步传送门:
Custom upload adapter - CKEditor 5 Documentationckeditor.com这里先说一下,官网教程的叙述顺序感觉是由全局到整体的方式,所以你如果顺着看,代码里会出现很多莫名其妙没有见过的变量,这个时候不要慌,看下去就是了,在后面都会一一解释的。
这里直接放上ckeditor组件的代码:
<template>
<ckeditor class='richTest' v-model='cont' :editor='editor' :config='editorConfig' :disabled='disabled'></ckeditor>
</template>
<script>
import ClassicEditor from '@ckeditor/ckeditor5-build-classic'
function customUploadAdapterPlugin (editor) {
editor.plugins.get('FileRepository').createUploadAdapter = (loader) => {
return new UploadAdapter(loader)
}
}
let vue = {}
class UploadAdapter {
constructor (loader) {
this.loader = loader
}
upload () {
return this.loader.file.then(file => new Promise((resolve, reject) => {
vue.$oss.uploadToOss(file).then(res => {
resolve({default: res.url, ...res})
}).catch(error => {
reject(error)
})
}))
}
abort () {
console.log('ckeditor: abort to insert image!')
}
}
export default {
name: 'ckeditor',
inject: ['errorMessage'],
props: {
content: {
type: String,
default: ''
},
disabled: {
type: Boolean,
default: false
}
},
data () {
return {
editor: ClassicEditor,
editorConfig: {
language: "zh-cn",
toolbar: ["heading", "|", "bold", "italic", "link", "bulletedList", "numberedList", "blockQuote", "imageUpload", "|", "undo", "redo"],
extraPlugins: [ customUploadAdapterPlugin ]
}
}
},
computed: {
cont: {
get: function () {
return this.content === null ? '' : this.content
},
set: function (newValue) {
this.$emit('getContent', newValue)
}
}
},
created () {
vue = this
}
}
</script>
<style scoped>
.richTest {
height: 31.25rem;
}
</style>
整个组件总共接收两个参数,一个方法:
参数:content
富文本内容,用于编辑功能的自动填充。
参数:disabled
设置是否只读。
方法:getContent
用于让父组件拿到这个组件的富文本内容。
需要注意的几点:
- 这里的vue.$oss.uploadToOss是我在oss配置文件里自定义的方法,它长成这样:
// 上传到 OSS
async uploadToOss (source) {
// el-upload的返回值file在raw里,ckeditor的直接就是file
const file = source.raw ? source.raw : source
const ext = file.name.split('.').pop()
const fileName = this.generateMixed(32) + '.' + ext
try {
let res = await this.client.multipartUpload(`HereIsFileUrl/${fileName}`, file)
return {...res, url: baseUrl + res.name}
} catch (e) {
throw new Error(e)
}
}
vue是当前vue组件实例,在created生命周期被赋予。
里面也提到了使用el-upload的回调和ckeditor的区别。
- 自定义ckeditor5高度的办法
<style lang="stylus">
#I_am_just_a_qualifier
.ck-rounded-corners .ck.ck-editor__main>.ck-editor__editable, .ck.ck-editor__main>.ck-editor__editable.ck-rounded-corners
height 100px
</style>
注意这里用id限定了一下作用域,避免样式全局污染。