preface

This article uses wangEditor V5 to implement the Vue2.6 editor. WangEditor V5 officially provides Vue components that are very simple to use. Vue3 can be referred to 50 lines of code Vue3 using a rich text editor.

WangEditor V5 is in public beta and questions and suggestions can be submitted to Github Issue.

[Note] The editor may be updated later, and the API and configuration may be adjusted. Please consult the documentation for questions and do not rely solely on this article.

The installation

Initialize a Vue2.6 environment using VUe-CLI, and then install

yarn add @wangeditor/editor @wangeditor/editor-for-vue
yarn add lodash.clonedeep You can also use other clonedeep functions if you want to implement deep copy
Copy the code

Pay attention to

  • Used for Vue2 installation@wangeditor/editor-for-vue
  • Used for Vue3 installation@wangeditor/editor-for-vue@next

Creating an editor

Write the code

Create a Vue component MyEditor. Vue, about 50 lines of code, logic is relatively clear (source code at the end of the article)

<template>
    <div style="border: 1px solid #ccc;">
        <! -- Toolbar -->
        <Toolbar
            style="border-bottom: 1px solid #ccc"
            :editorId="editorId"
            :defaultConfig="toolbarConfig"
        />
        <! -- Editor -->
        <Editor
            style="height: 500px"
            :editorId="editorId"
            :defaultConfig="editorConfig"
            :defaultContent="getDefaultContent" <!--Notice that this is used herecomputedThe results of the-->
            @onChange="onChange"
        />
    </div>
</template>

<script>
import { Editor, Toolbar, getEditor, removeEditor } from '@wangeditor/editor-for-vue'
import cloneDeep from 'lodash.clonedeep'

export default {
    name: 'MyEditor'.components: { Editor, Toolbar },
    data() {
        return {
            editorId: 'wangEditor-1'.// Define an editor ID that is globally unique and invariant. Important!!
            defaultContent: [].// The editor's default content, used only during initialization
            latestContent: [].// Used to store the latest contents of the editor, modified when onChange
            toolbarConfig: {},
            editorConfig: {
                placeholder: 'Please enter... ',}}},computed: {
        getDefaultContent() {
            return cloneDeep(this.defaultContent) // Deep copy, important!!}},methods: {
        onChange(editor) {
            console.log('onChange', editor.children) // get the latest contents of the editor when onChange
            this.latestContent = editor.children
        },
    },
    beforeDestroy() {
        const editor = getEditor(this.editorId)
        if (editor == null) return
        editor.destroy() // Destroy the editor immediately when the component is destroyed, important!!
        removeEditor(this.editorId)
    },
}
</script>

<! Remember to import the wangEditor CSS file, important!! -->
<style src="@wangeditor/editor/dist/css/style.css"></style>
Copy the code

run

Introduce myeditor. vue into app. vue to generate a full-featured editor. When the content changes, the onChange function is triggered in real time.

Matters needing attention

  • The editor ideditorIdTo be globally unique, no duplication, no change
  • Editor default contentdefaultContentMake a deep copy or an error will be reported
  • The default content passed into the editor is in JSON format (not HTML), and the data structure is referenced here
  • Destroy the editor when the Vue component is destroyed

Ajax gets the content asynchronously and creates the editor

First, add an attribute isAjaxDone: false to the component data, and after ajax, change this.isajaxdone = true

mounted() {
    // Simulate Ajax requests, asynchronous render editor
    setTimeout(() = > {
        // Assign the content to the Ajax request
        this.defaultContent = [
            {
                type: 'paragraph'.children: [{ text: 'Ajax asynchronously retrieved Content'}],}]this.isAjaxDone = true
    }, 1500)},Copy the code

Then, use v-if=”isAjaxDone” to control the editor’s rendering.

<template>
    <div style="border: 1px solid #ccc;" v-if="isAjaxDone">
        <! -- Toolbar -->
        <Toolbar . />
        <! -- Editor -->
        <Editor . />
    </div>
</template>
Copy the code

configuration

Editor configuration

Only placeholder is configured as an example in the code above. It also supports readOnly autoFocus maxLength and other configurations, refer to the documentation.

editorConfig: {
    placeholder: 'Please enter... '.// Continue with other configurations...
},
Copy the code

Note, however, that all callback functions in this document cannot be passed in as configurations, such as onCreated onChange onDestroyed, etc. These callbacks must be passed in as Vue events.

<Editor
    :editorId="editorId"
    :defaultConfig="editorConfig"
    :defaultContent="getDefaultContent"

    <!--The callback function toVueThe event form-->
    @onCreated="onCreated"
    @onChange="onChange"
    @onDestroyed="onDestroyed"
    @onMaxLength="onMaxLength"
    @onFocus="onFocus"
    @onBlur="onBlur"
    @customAlert="customAlert"
    @customPaste="customPaste"
/>
Copy the code

Toolbar Configuration

You can use this configuration if you want to modify the toolbar menus, such as hiding certain menus or reordering groups. Support for toolbarKeys and excludeKeys, refer to the documentation.

toolbarConfig: {
    toolbarKeys: [ /* What menus to display, how to sort and group */].excludeKeys: [ /* Which menus to hide */],},Copy the code

Configuration menu

If you want to configure a menu, such as setting the color, font, font size, setting the API address for uploading pictures, etc., you can use the menu configuration. Specific reference documents.

editorConfig: {
    placeholder: 'Please enter... '.// All menu configurations must be under the MENU_CONF property
    MENU_CONF: {
        // Configure the size
        fontSize: [...]. .// Configure uploading images
        uploadImage: {... },// Continue with other menu configurations...}},Copy the code

API

WangEditor provides a rich API to help you with any editor operation. Refer to the documentation.

  • Configure the related apis
  • Content handling related apis
  • Apis for node operations
  • API for selection operations
  • An API for custom events

After the editor is created, you can get an instance of the Editor through getEditor(editorId) and then execute the API.

methods: {
    // Execute the function by clicking a button
    getEditorText() {
        const editor = getEditor(this.editorId)
        if (editor == null) return

        console.log(editor.getText()) // Execute the Editor API}},Copy the code

Get the content and store it on the server

The content of the editor is in JSON format. For example, the data format of a piece of text is:

[{"type":"paragraph"."children": [{"text":"Textual content"}]}]
Copy the code

The content is retrieved via editor.children and ajax submitted to the server. Of course, you can also use onChange to synchronize the content to

You can getHtml content using editor.gethtml (). Note, however, that if you save only the HTML content, you cannot edit it again. This is because when the editor initializes, it can only pass content in JSON format, not HTML.

According to the content

Get the content of the editor from the server, create an instance of the Editor, get the HTML and plain text, and then render the page.

import { createEditor } from '@wangeditor/editor'

const editor = createEditor({
    content
})

editor.getHtml()
editor.getText()
Copy the code

PS: If you want to do server-side rendering SSR, this code can also be run in NodeJS

conclusion

All source code for this article is here.

WangEditor V5 is in public beta and questions and suggestions can be submitted to Github Issue.