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>
 |