130 lines
3.3 KiB
Vue
130 lines
3.3 KiB
Vue
<template>
|
|
<section class="AiEditor" :class="{invalid:valid&&!validateState}">
|
|
<ck-editor v-if="sourceEditor" :editor="sourceEditor" v-model="content" :config="editorConfig" @ready="handleReady" @input="$emit('change',repairContent)"/>
|
|
</section>
|
|
</template>
|
|
|
|
<script>
|
|
/**
|
|
* 原组件ckeditor封装
|
|
* 修改者:Kubbo
|
|
*/
|
|
import CKEditor from '@ckeditor/ckeditor5-vue2'
|
|
import {UploadAdapter} from "./models";
|
|
|
|
export default {
|
|
name: "AiEditor",
|
|
components: {ckEditor: CKEditor.component},
|
|
inject: {
|
|
elFormItem: {default: ""},
|
|
elForm: {default: ''},
|
|
},
|
|
model: {
|
|
prop: "value",
|
|
event: "change"
|
|
},
|
|
props: {
|
|
value: {type: String, required: true, default: ""},
|
|
placeholder: {type: String, default: '请输入正文'},
|
|
conf: Object,
|
|
instance: {type: Function, required: true},
|
|
valid: {type: Boolean, default: true},
|
|
text: {default: ""},
|
|
action: {default: "/admin/file/add"},
|
|
params: {default: () => ({})},
|
|
mode: {default: "default"}
|
|
},
|
|
data() {
|
|
return {
|
|
sourceEditor: null,
|
|
editor: null,
|
|
isPasteStyle: true,//粘贴是否携带格式
|
|
content: ""
|
|
}
|
|
},
|
|
computed: {
|
|
validateState() {
|
|
return ['', 'success'].includes(this.elFormItem?.validateState)
|
|
},
|
|
editorConfig() {
|
|
return {
|
|
mediaEmbed: {
|
|
previewsInData: true
|
|
},
|
|
htmlSupport: {
|
|
allow: [{name: /[\s\S]+/, styles: true, classes: true, attributes: true}]
|
|
},
|
|
...this.conf
|
|
}
|
|
},
|
|
repairContent: v => `<section class="ck-content">${v.content?.replace(/\s0w"/g, '"')?.replace(/srcset/g, 'src')}</section>`
|
|
},
|
|
watch: {
|
|
content(v) {
|
|
v && this.dispatch('ElFormItem', 'el.form.change', [v])
|
|
}
|
|
},
|
|
methods: {
|
|
handleReady(editor) {
|
|
this.editor = editor
|
|
const {instance, action, params} = this
|
|
editor.plugins.get('FileRepository').createUploadAdapter = loader => new UploadAdapter(loader, instance, action, params)
|
|
},
|
|
/**
|
|
* 表单验证
|
|
* @param componentName
|
|
* @param eventName
|
|
* @param params
|
|
*/
|
|
dispatch(componentName, eventName, params) {
|
|
let parent = this.$parent || this.$root;
|
|
let name = parent.$options.componentName;
|
|
|
|
while (parent && (!name || name !== componentName)) {
|
|
parent = parent.$parent;
|
|
|
|
if (parent) {
|
|
name = parent.$options.componentName;
|
|
}
|
|
}
|
|
if (parent) {
|
|
parent.$emit.apply(parent, [eventName].concat(params));
|
|
}
|
|
},
|
|
initValue() {
|
|
let unwatch = this.$watch('value', (v) => {
|
|
const init = v.replace(/<section class="ck-content">(.*)<\/section>/, '$1')
|
|
if (!!this.content) unwatch && unwatch()
|
|
else if (!!init) {
|
|
this.content = init
|
|
unwatch && unwatch()
|
|
}
|
|
}, {immediate: true})
|
|
},
|
|
loadEditor(count = 0) {
|
|
if (!!window?.ClassicEditor) {
|
|
this.sourceEditor = ClassicEditor
|
|
this.initValue()
|
|
} else if (count < 10) {
|
|
setTimeout(() => this.loadEditor(++count), 50)
|
|
} else {
|
|
console.error("无法加载编辑器资源,请联系管理员")
|
|
}
|
|
}
|
|
},
|
|
created() {
|
|
this.$injectLib("https://cdn.cunwuyun.cn/ckeditor.js", () => {
|
|
this.loadEditor()
|
|
})
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.AiEditor {
|
|
:deep(.ck-content ){
|
|
min-height: 300px;
|
|
}
|
|
}
|
|
</style>
|