vue rich text editor quill (including code highlighting, custom fonts, Chineseization, mouse hover prompts, component packaging, etc.)

Basic use
Install dependencies

npm i quill

.vue file

<div ref="editor" :style="finalStyle"></div>

“quill”;

import "quill/dist/quill.snow.css";
= {
                    theme: "snow",
                    placeholder: "Please enter here",
                    modules: {
                        toolbar: {
                            container: [
                                // [{ 'header': 1 }, { 'header': 2 }], // Header - independent tiles
                                [{header: [1, 2, 3, 4, 5, 6, false]}], // Title - drop-down selection
                                [{size: ["small", false, "large", "huge"]}], // font size
                                [{list: "ordered"}, {list: "bullet"}], // Ordered and unordered lists
                                ["blockquote", "code-block"], // quote code block
                                //The link button needs to select the text and then click it
                                ["link", "image", "video"], // Links, pictures, videos
                                [{align: []}], // Alignment // text direction
                                [{indent: "-1"}, {indent: " + 1"}], // indent
                                ["bold", "italic", "underline", "strike"], // bold italic underline strikethrough
                                [{color: []}, {background: []}], // Font color, font background color
                                [{'script': 'sub'}, {'script': 'super'}], // subscript/superscript
                                [{'font': []}],//Font
                                ["clean"], // Clear text format
                            ]
                        }
                    }
                }

new Quill(this.$refs.editor, Options)

code highlighting
Need to install dependencies

npm i highlight.js

‘highlight.js’

import 'highlight.js/styles/monokai-sublime.css'

Add the following syntax in the modules of Options

:{
   syntax: {
      highlight: text => {
        return hljs.highlightAuto(text).value; //This is where code highlighting needs to be configured
      }
   },

Custom font

//Custom font
let fontList = ['SimSun', 'SimHei', 'Microsoft-YaHei', 'KaiTi', 'FangSong']
Quill.import('formats/font').whitelist = fontList; //Add fonts to the whitelist

Pass in fontList in the Options toolbar

[{'font': fontList}],//Font

Chinese
Mainly implemented through css

.ql-snow .ql-tooltip[data-mode="link"]::before {
        content: "Please enter the link address:";
    }

    .ql-snow .ql-tooltip.ql-editing a.ql-action::after {
        border-right: 0px;
        content: "Save";
        padding-right: 0px;
    }

    .ql-snow .ql-tooltip[data-mode="video"]::before {
        content: "Please enter the video address:";
    }

    .ql-snow .ql-picker.ql-size .ql-picker-label::before,
    .ql-snow .ql-picker.ql-size .ql-picker-item::before {
        content: "14px";
    }

    .ql-snow .ql-picker.ql-size .ql-picker-label[data-value="small"]::before,
    .ql-snow .ql-picker.ql-size .ql-picker-item[data-value="small"]::before {
        content: "10px";
    }

    .ql-snow .ql-picker.ql-size .ql-picker-label[data-value="large"]::before,
    .ql-snow .ql-picker.ql-size .ql-picker-item[data-value="large"]::before {
        content: "18px";
    }

    .ql-snow .ql-picker.ql-size .ql-picker-label[data-value="huge"]::before,
    .ql-snow .ql-picker.ql-size .ql-picker-item[data-value="huge"]::before {
        content: "32px";
    }

    .ql-snow .ql-picker.ql-header .ql-picker-label::before,
    .ql-snow .ql-picker.ql-header .ql-picker-item::before {
        content: "text";
    }

    .ql-snow .ql-picker.ql-header .ql-picker-label[data-value="1"]::before,
    .ql-snow .ql-picker.ql-header .ql-picker-item[data-value="1"]::before {
        content: "Title 1";
    }

    .ql-snow .ql-picker.ql-header .ql-picker-label[data-value="2"]::before,
    .ql-snow .ql-picker.ql-header .ql-picker-item[data-value="2"]::before {
        content: "Title 2";
    }

    .ql-snow .ql-picker.ql-header .ql-picker-label[data-value="3"]::before,
    .ql-snow .ql-picker.ql-header .ql-picker-item[data-value="3"]::before {
        content: "Title 3";
    }

    .ql-snow .ql-picker.ql-header .ql-picker-label[data-value="4"]::before,
    .ql-snow .ql-picker.ql-header .ql-picker-item[data-value="4"]::before {
        content: "Title 4";
    }

    .ql-snow .ql-picker.ql-header .ql-picker-label[data-value="5"]::before,
    .ql-snow .ql-picker.ql-header .ql-picker-item[data-value="5"]::before {
        content: "Title 5";
    }

    .ql-snow .ql-picker.ql-header .ql-picker-label[data-value="6"]::before,
    .ql-snow .ql-picker.ql-header .ql-picker-item[data-value="6"]::before {
        content: "Title 6";
    }

    .ql-snow .ql-picker.ql-font .ql-picker-label[data-value=SimSun]::before,
    .ql-snow .ql-picker.ql-font .ql-picker-item[data-value=SimSun]::before {
        content: "宋体";
    }

    .ql-font-SimSun {
        font-family: "SimSun";
    }

    .ql-snow .ql-picker.ql-font .ql-picker-label[data-value=SimHei]::before,
    .ql-snow .ql-picker.ql-font .ql-picker-item[data-value=SimHei]::before {
        content: "Heold";
    }


    .ql-font-SimHei {
        font-family: "SimHei";
    }

    .ql-snow .ql-picker.ql-font .ql-picker-label[data-value=Microsoft-YaHei]::before,
    .ql-snow .ql-picker.ql-font .ql-picker-item[data-value=Microsoft-YaHei]::before {
        content: "Microsoft Yahei";
    }

    .ql-font-Microsoft-YaHei {
        font-family: "Microsoft YaHei";
    }

    .ql-snow .ql-picker.ql-font .ql-picker-label[data-value=KaiTi]::before,
    .ql-snow .ql-picker.ql-font .ql-picker-item[data-value=KaiTi]::before {
        content: "楷体";
    }

    .ql-font-KaiTi {
        font-family: "KaiTi";
    }

    .ql-snow .ql-picker.ql-font .ql-picker-label[data-value=FangSong]::before,
    .ql-snow .ql-picker.ql-font .ql-picker-item[data-value=FangSong]::before {
        content: "Imitate Song Dynasty";
    }

    .ql-font-FangSong {
        font-family: "FangSong";
    }

Mouse hover prompt
Just execute the method after new Quill

new Quill(this.$refs.editor, Options);
this.addQuillTitle();
addQuillTitle() {
                const titleConfig = {
                    'ql-bold': 'bold',
                    'ql-color': 'color',
                    'ql-font': 'Font',
                    'ql-code': 'Insert code',
                    'ql-italic': 'italic',
                    'ql-link': 'Add link',
                    'ql-background': 'Background color',
                    'ql-size': 'Font size',
                    'ql-strike': 'strikethrough',
                    'ql-script': 'Superscript/Subscript',
                    'ql-underline': 'underline',
                    'ql-blockquote': 'Quote',
                    'ql-header': 'Title',
                    'ql-indent': 'indent',
                    'ql-list': 'list',
                    'ql-align': 'Text alignment',
                    'ql-direction': 'Text direction',
                    'ql-code-block': 'code block',
                    'ql-formula': 'formula',
                    'ql-image': 'picture',
                    'ql-video': 'video',
                    'ql-clean': 'Clear font style'
                }
                let oToolBar = document.querySelector('.ql-toolbar')
                if (!oToolBar) {
                    return
                }
                let aButton = oToolBar.querySelectorAll('button')
                let aSelect = oToolBar.querySelectorAll('select')
                aButton.forEach(function (item) {
                    if (item.className === 'ql-script') {
                        item.value === 'sub' ? item.title = 'subscript' : item.title = 'superscript'
                    } else if (item.className === 'ql-indent') {
                        item.value === ' + 1' ? item.title = 'Indent to the right' : item.title = 'Indent to the left'
                    } else {
                        item.title = titleConfig[item.classList[0]]
                    }
                })
                aSelect.forEach(function (item) {
                    item.parentNode.title = titleConfig[item.classList[0]]
                })
            }

Component encapsulation
pub-editor_quill.vue



Instructions

<pub-editor_quill
                v-model="content"
                @blur="onEditorBlur()"
                @focus="onEditorFocus()"
                @change="onEditorChange()"
        />
data() {
            return {
                content: 'Editor's initial value',
            }
        },