current position:Home>Rich text editor: ckeditor (using ckeditor4 Vue)

Rich text editor: ckeditor (using ckeditor4 Vue)

2022-04-29 04:24:42gao_ grace

lately ,vue The project uses a rich text editor , After repeated research , I chose ckeditor,ckeditor It is divided into 4 and 5, We chose 4, There are few Chinese related materials on the Internet , Summarize the experience of using .
Official website :https://ckeditor.com/ckeditor-4/, There are downloads , Documents, etc. ,Add-ons There's an extra plugin.

structure vue project

use first vue create ckeditor_example_1 establish vue project , Because our control uses element-ui, Therefore, before entering the project, download the control npm install --save element-ui.

Use ckeditor4-vue Build a basic rich text editor

stay vue Project use ckeditor4 There are two ways , One is to go to the official website to download ckeditor My bag , Unzip and put it in the project , The other is to use their packaged ckeditor4-vue package , here , We used the package , Use command npm install --save ckeditor4-vue Download package .
then , Create editor file Editor.vue:

<template>
  <div>
    <ckeditor ref="editor" :config="config" v-model="editorData"
              @namespaceloaded="onNamespaceLoaded" @ready="onEditorReady"></ckeditor>
  </div>
</template>

<script>
  export default {
    
    name: 'Editor',
    data () {
    
      return {
    
        editorData: ''
      }
    },
    props: {
    
      config: {
    
        type: Object,
        default: () => {
    }
      },
      ready: {
    
        type: Function,
        default: () => {
    }
      }
    },
    methods: {
    
      onNamespaceLoaded (CKEDITOR) {
    
        console.log(CKEDITOR)
      },
      onEditorReady (editor) {
    
        this.ready(editor)
      }
    }
  }
</script>

<style scoped>

</style>

Such a basic ckeditor It's built , Reference the file where you want to use it <editor ref="editor"></editor>.
Look at the <ckeditor ref="editor" :config="config" v-model="editorData" @namespaceloaded="onNamespaceLoaded" @ready="onEditorReady"></ckeditor> This line of code , It should be noted that editorData Is the text content in the editor ;config Is the editor's configuration file , If the basic editor can meet your requirements , You can not configure config, Use this object , You can configure multiple different in a project editor;onNamespaceLoaded Dealing with global variables CKEDITOR Completed Events , in other words , This can only be used after window.CKEDITOR Variable ;onEditorReady Handle the event that the editor object construction is completed , in other words , After that , Only the current editor object can be used , For example, insert text and other operations .
 Default editor image
The above figure shows the default editor style ( I changed the background color myself ), Let's talk about its additional functions .

Extra functions

Modify the configuration file

config There are many configuration items in it , We can modify it directly CKEDITOR.config Affect all editor, You can also give a separate editor To configure config.

https://ckeditor.com/docs/ckeditor4/latest/api/CKEDITOR_config.html

Now let's talk about , Basic editor Problems encountered , And how to configure config solve

1. Copy from elsewhere HTML page , Paste , Only the text is preserved
Add... In the configuration file allowedContent: true and pasteFilter: null Remove the filtering function of text .
2. The height of the editor is too low , Fall short of expectations
Add... In the configuration file height: 500 Configure the height of the editor
3. Want to specify the language as English
Add... In the configuration file language: 'en' Configure the language of the editor
4. Want to customize the editor toolbar
Add... In the configuration file toolbar Configuration item for , The content format is as follows :

        toolbar: [
            {
    
              name: 'code',
              items: ['Source']
            },
            {
    
              name: 'basicstyles',
              items: [ 'Styles', '-', 'Bold', 'Italic', 'Strike', 'Underline', 'TextColor', 'BGColor', 'Font', 'FontSize' ]
            },
            {
    
              name: 'styles',
              items: ['RemoveFormat']
            },
            {
    
              name: 'insert',
              items: [ 'Table',  "SpecialChar", "HorizontalRule", 'CodeSnippet']
            }
            ,
            '/',
            {
    
              name: 'paragraph',
              items: ['Format', 'NumberedList', 'BulletedList','-', 'Indent', 'Outdent', '-', 'JustifyLeft', 'JustifyCenter', 'JustifyRight' ]
            },
            {
    
              name: 'links',
              items: ['Link', 'Unlink']
            },

            {
    
              name: 'document',
              items: ['Undo', 'Redo']
            }
          ]

among ,{} There are groups ,’/' Means line break ,items It is concrete. button, Specifically button Name , You can look at the source code yourself , Anyway, I didn't find all the information in the document toolbar button The content of .
Be careful , My configuration here uses a lot of extra plugin, If you don't have a configuration extraPlugins Words , Direct use may lead to errors . Additional... Used here plugin Yes colorbutton, colordialog, dialog, indentblock, indentlist, justify, font, codesnippet, these plugin You don't have to define it , Can be directly in extraPlugins The configuration inside can be used .

Customize plugin

So let's talk about that , If you want to define a plug-in by yourself , What to do .
ckeditor Bring it with you image plug-in unit , I think it's too troublesome to use , So I defined a plug-in for uploading pictures . The plug-in code is as follows :

import img from '../../assets/img.png'

export default {
    
  init () {
    
    window.CKEDITOR.plugins.add('myImage', {
    
      icons:"myImage",
      init: function(editor){
    
        editor.addCommand("myImage", {
    
          exec: function( editor ) {
    
            let file = document.createElement('input')
            file.type = 'file'
            file.accept = 'image/*'
            file.addEventListener('change', () => {
    
              const reader = new FileReader();
              reader.readAsDataURL(file.files[0]);
              reader.onload = () => {
    
                editor.insertHtml(`<img src="${
      reader.result}"/>`)
              };
              reader.onerror = error => {
    
                console.error(error)
              };
            })
            file.click()
          }
        });
        editor.ui.addButton('MyImage',{
    
          label:'Insert Image',
          icon:  img,
          command:'myImage'
        });
      }
    })
  }
}

The path to the plug-in is /src/components/plugins/myImage.js, Icons use assets Inside img.png( I picked it directly ckeditor The icon , Then cut it yourself , And his image Icons are as like as two peas. ).window.CKEDITOR.plugins.add('myImage' This line of code is the main code for adding the plug-in ,myImage Is my plugin name ;editor.addCommand Add a command , Click on button Execute it when you need it , The way to do it is exec;editor.ui.addButton Add our own button, Inside command Configure previously defined command that will do , Click on button Execute the command when . What the above code does is , Click Add imagebutton When , Open the upload file dialog, Then you choose a picture , Turn it into base64 Insert editor In . You can modify the code , Choose to upload the picture to your own server , then , Insert the url.
ok , The plug-in is written , however , Not called yet , Where should we call ? You can see that we used window.CKEDITOR Variable , Therefore, after the variable generation is completed , Call again , It's recommended to put onNamespaceLoaded It calls .

import myImage from './plugins/myImage'
export default {
    
    name: 'Editor',
    methods: {
    
      onNamespaceLoaded (CKEDITOR) {
    
        console.log(CKEDITOR)
        myImage.init()
      }
   }
}

plugin Sign up , So our toolbar Is there directly in it ? Not at all , You also need to configure config Of documents extraPlugins, Put the registered plugin add , To configure toolbar, Put the registered button add , as for toolbar The location of , You can also write plugin When defining, specify , You can read the documents yourself .

config : {
    
	extraPlugins: 'myImage',
	toolbar: [
	  {
    
	  	name: 'insert',
        items: [ 'MyImage', 'Table',  "SpecialChar", "HorizontalRule", 'CodeSnippet']
      }
	]
}

thus , Just customize the plug-in . After starting , Find out ,button Your picture doesn't show , After investigation ,vue Package small pictures into base64, In this case ,ckeditor It doesn't show , modify vue Configuration file for
vue.config.js( If not , Add... Yourself , This is a new version vue, Old version , May be to modify their own webpack The configuration file ), Cancel the packaging of small files into base64 Configuration of .

module.exports = {
    
  // ......
  devServer: {
    
    disableHostCheck: true,
    port: 59999
  },
  chainWebpack: config => {
    
    config.module
           .rule('images')
           .use('url-loader')
           .loader('url-loader')
           .tap(options => Object.assign(options, {
     limit: 0 }))
  },
  configureWebpack: {
    
    plugins: [
    ]
  }
}

This is just a simple custom plug-in , Not used dialog, Not used panel.
ckeditor Definition dialog Words , Configuration is a hassle , And the style is inconsistent with our project , Changing the style is also troublesome . therefore , I made a detour , Use your own dialog, Here is a brief introduction , How to use your own dialog.
Self contained table Of dialog:
 Self contained table Of dialog
My custom insert div Of dialog:
 Insert picture description here

This is my own dialog Definition of plug-ins :

import d from '../../assets/div.png'

export default {
    
  init () {
    
    window.CKEDITOR.plugins.add('myDialog', {
    
      icons:"myDialog",
      init: function(editor){
    
        editor.addCommand("myDialog", {
    
          exec: function( editor ) {
    
            console.log(editor)
            editor.dialog.show()
          }
        });
        editor.ui.addButton('MyDialog',{
    
          label:'Show Dialog',
          icon:  d,
          command:'myDialog'
        });
      }
    })
  }
}

We define a button, Execute code when clicked editor.dialog.show(), Among them dialog It's our custom dialog, It has a method called show, Display dialog. that , This dialog Where did you join editor Of this object ?editor The object is ckeditor Built in objects for , With theout our dialog This object , Remember when I defined it before @ready="onEditorReady" Do you ? Yes , We can define in onEditorReady Method inside .

onEditorReady (editor) {
    
    editor.dialog = this.$refs.dialog
}

among ,this.$refs.dialog It's our custom dialog object . as for dialog The specific definition of , You can create one yourself dialog.vue file , Customize .

monitor editor Events

	onEditorReady (editor) {
    
        // monitor paste event , Handle copy/paste picture 
        editor.on( 'paste', async evt => {
    
          if(evt.data.dataTransfer.getFilesCount() > 0) {
    
            evt.data.dataValue = ''
            let res = await this.handleTransferImage(evt)
            if(res){
    
              editor.insertHtml(`<img src="${
      res.url}"/>`)
            }
          }
        })
        // monitor key Events , Realization tab When , call indent command 
        editor.on( 'key', function( event ) {
    
          let keycode = event.data.keyCode;
          if( keycode == 9 ) {
    
            event.cancel();
            editor.execCommand('indent')
          }
        })
      },

Other basic functions

      // Customize ckeditor Background color and font color 
      onNamespaceLoaded (CKEDITOR) {
    
        CKEDITOR.addCss(`body{background: #7b8b6f;color: white;}`)
      },
	  // Set up editor Of html Text content 
	  setContent (data) {
    
        this.editorData = data
        //this.$refs.editor.instance.setData(data)
      },
      // obtain editor Of html Text content 
      getContent () {
    
        //return this.$refs.editor.instance.getData()
        return this.editorData
      },
      // Insert the specified... At the mouse html
      insertHtml (html) {
    
        this.$refs.editor.instance.insertHtml(html)
      },
      // perform editor Built in command
      execCommand (command) {
    
        this.$refs.editor.instance.execCommand(command)
      },
      // take editor Set to readonly Of 
      setReadonly (readonly) {
    
        this.$refs.editor.instance.setReadOnly(readonly)
      },
      // Judge whether it is readonly Of 
      isReadonly () {
    
        return this.$refs.editor.instance.readOnly
      },
      //disable/enable designated command
      setDisable(command, disable) {
    
        if(disable) {
    
          this.$refs.editor.instance.commands[command].enable()
        } else {
    
          this.$refs.editor.instance.commands[command].disable()
        }
      },
      // Get the specified command, such as 'source'
      getCommand (command) {
    
        return this.$refs.editor.instance.commands[command]
      }

Problems encountered

1. Official website Add-ons The plug-ins inside cannot be used directly , You must download the source code yourself and rewrite it
2. All of them are cdn Resources for , Corporate network problems , It's very slow , Initialization requires 10s about , It's hard to accept

Due to corporate network problems , There is no way to use ckeditor Of cdn, Last , Give up the use of ckeditor4-vue, I went to the official website to download ckeditor Resource pack for , Decompress it and put it into the project for use , Next time, let's introduce , How to do this .

Code warehouse :https://github.com/gaograce/ckeditor-vue-example1.git

copyright notice
author[gao_ grace],Please bring the original link to reprint, thank you.
https://en.qdmana.com/2022/118/202204280552145587.html

Random recommended