ck-editor自定义组件

786 阅读2分钟

ck-editor自定义组件

前置说明

1.官网资料&使用版本

1.https://ckeditor.com/docs/ckeditor5/latest/
2.ck5-20.0版本

相关的章节

view-model

菜单增加按钮

基本思路

1.注册插件
2.实现一个按钮在toolbar栏
2.1针对点击命令执行对应命令
4.将内容插入到页面中

demo 实现一个上传音频的功能

1.注册插件

import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
import AudioUI from './ui';
import AudioCommand from './command';
import { AUDIO } from './utils';
import './index.less';
export default class AudioPlugin extends Plugin {
	static get requires() {
		return [ AudioUI, AudioCommand ];
	}
	static get pluginName() {
		return 'InsertAudio';
	}

	constructor( editor ) {
		super( editor );
		this.editor = editor;
	}

	async init() {
		const editor = this.editor;
		// 注册命令
		editor.commands.add( AUDIO, new AudioCommand( editor ) );
	}
}

说明: 1.每一个插件必须继承Plugin类
2.requires表示依赖的内容,加载完成才会执行此组件的实例化 3.在init中注册AUDIO命令

2.实现一个按钮在toolbar栏

import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
import FileDialogButtonView from './uploadView';
import audioIcon from './icon.svg';
import { generateFile } from 'utils/file';
import upload from 'utils/uploadwrapper';

export default class AudioUI extends Plugin {
	constructor(editor) {
		super(editor);
		this.editor = editor;
	}

	init() {
		const editor = this.editor;
		editor.ui.componentFactory.add('audio', (locale) => {
			const view = new FileDialogButtonView(locale);
			const command = editor.commands.get('audio');
			const imageTypes = 'audio/mpeg';

			view.set({
				acceptedType: imageTypes,
				allowMultipleFiles: false,
			});

			view.buttonView.set({
				label: '插入音频',
				icon: audioIcon,
				tooltip: true,
			});

			view.on('done', async (evt, files) => {
				if (!files || !files.length) {
					return false;
				}
				const file = files[0];
				if (file.size / (1024 * 1024) > 10) {
					window.alert('文件大小限制为20M');
					return false;
				}

				// 校验格式
				if (file.type !== 'audio/mpeg') {
					window.alert('请选择mp3格式的音频');
					return false;
				}
				// 上传
				const uploadConfig = this.editor.getUploadConfig();
				const audioFile = generateFile(file, 'string', 'mp3');
				const audioUrl = await upload(audioFile, uploadConfig.tokenUrl, uploadConfig.businessKey).catch(err => {
					console.log('upload err:', err);
					return '';
				});
				console.log('audioUrl:', audioUrl);
				command.execute(audioUrl);
			});
			return view;
		});
	}
}

说明: 1.注册一个按钮组件,然后在初始化组件的时候使用对应的组件

AxxEditor.defaultConfig = {
    toolbar: {
	items: ['audio'],
    }
};

2.在这个组件中具体实现思路是写个组件,这个组件的点击事件中触发上传逻辑,然后调用自己写好的上传逻辑上传完成,再调用done将内容添加到页面上

3.将内容插入到页面中

import Command from '@ckeditor/ckeditor5-core/src/command';

class InsertAudioCommand extends Command {
	execute(url) {
		// 插入到页面
		this._insert({src: url})
	}

	_insert(attrs) {
		const model = this.editor.model;
		const selection = model.document.selection;
		const curElement = selection.getSelectedElement();

		model.change((writer) => {
			const curAttrs = {}
			if (curElement) {
				for(let [key, value] of curElement.getAttributes()) {
					curAttrs[key] = value
				}
				writer.remove(curElement);
			}
			const element = writer.createElement( 'audio', { ...curAttrs, ...attrs, controlslist: 'nodownload' } );

			model.insertContent(element, selection.getFirstPosition());
			writer.setSelection(element, 'on');
		});
	}
}
export default InsertAudioCommand;

实现一个命令,在上传完音频之后将内容插入到页面