vue partially uses vue-quill-editor rich text editor

1. Install vue-quill-editor

npm install vue-quill-editor -save

2. Introduce a rich text editor locally into the component

<script>
//Rich text editor
import 'quill/dist/quill.core.css'
import 'quill/dist/quill.snow.css'
import 'quill/dist/quill.bubble.css'

import {<!-- --> Quill, quillEditor } from "vue-quill-editor";
export default {<!-- -->
data(){<!-- -->
return {<!-- -->
content:'',
}
}
components: {<!-- -->quillEditor},
}
</script>

3. HTML

<!--Rich text editor-->
<quill-editor
  class="ql-editor"
  ref="myTextEditor"
  v-model="content"
  :options="editorOption"
  @blur="onEditorBlur($event)"
  @focus="onEditorFocus($event)"
  @change="onEditorChange($event)"
>
</quill-editor>

4. JS, usually written in methods and mounted

methods: {<!-- -->
// Lost focus event
    onEditorBlur(quill) {<!-- -->
      console.log('editor blur!', quill)
    },
    //Get focus event
    onEditorFocus(quill) {<!-- -->
      console.log('editor focus!', quill)
    },
    // Prepare rich text editor
    onEditorReady(quill) {<!-- -->
      console.log('editor ready!', quill)
    },
    //Content change event
    onEditorChange({<!-- --> editor, html, text }) {<!-- -->
      this.content = html;
    },
}
mounted() {<!-- -->
    // Custom font size
    const Size = Quill.import('attributors/style/size')
    Size.whitelist = ['10px', '12px', '16px', '18px', '20px', '30px', '32px']
    Quill.register(Size, true)

    // Custom font type
    const fonts = ['SimSun', 'SimHei', 'Microsoft-YaHei', 'KaiTi', 'FangSong', 'Arial', 'sans-serif'] ;
    const Font = Quill.import('formats/font');
    Font.whitelist = fonts
    Quill.register(Font, true)
  }

5. Style (less)

<style scoped lang="less">
@import "quill";
</style>

6. Create a new quill.less file in the same directory

// Add height and scroll bar to text content
.quill-editor /deep/ .ql-container {<!-- -->
  min-height: 220px;
}

.ql-container {<!-- -->
  min-height: 230px;
}

/deep/.ql-editor
{<!-- -->
  padding: 0px 10px;
  .ql-snow .ql-tooltip [data-mode="link"]::before {<!-- -->
    content: "Please enter the link address:";
    left: 0;
  }

  .ql-snow .ql-tooltip.ql-editing {<!-- -->
    left: 0 !important;
  }

  .ql-snow .ql-tooltip {<!-- -->
    left: 0 !important;
  }

  .ql-snow .ql-editor {<!-- -->
    max-height: 300px;
  }

  .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" !important;
    font-size: 14px;
  }

  .ql-snow .ql-picker.ql-size .ql-picker-label[data-value="10px"]::before, .ql-snow .ql-picker.ql-size .ql-picker- item[data-value="10px"]::before {<!-- -->
    content: "10px" !important;
    font-size: 10px;
  }

  .ql-snow .ql-picker.ql-size .ql-picker-label[data-value="12px"]::before, .ql-snow .ql-picker.ql-size .ql-picker- item[data-value="12px"]::before {<!-- -->
    content: "12px" !important;
    font-size: 12px;
  }

  .ql-snow .ql-picker.ql-size .ql-picker-label[data-value="16px"]::before, .ql-snow .ql-picker.ql-size .ql-picker- item[data-value="16px"]::before {<!-- -->
    content: "16px" !important;
    font-size: 16px;
  }

  .ql-snow .ql-picker.ql-size .ql-picker-label[data-value="18px"]::before, .ql-snow .ql-picker.ql-size .ql-picker- item[data-value="18px"]::before {<!-- -->
    content: "18px" !important;
    font-size: 18px;
  }

  .ql-snow .ql-picker.ql-size .ql-picker-label[data-value="20px"]::before, .ql-snow .ql-picker.ql-size .ql-picker- item[data-value="20px"]::before {<!-- -->
    content: "20px" !important;
    font-size: 20px;
  }

  .ql-snow .ql-picker.ql-size .ql-picker-label[data-value="30px"]::before, .ql-snow .ql-picker.ql-size .ql-picker- item[data-value="30px"]::before {<!-- -->
    content: "30px" !important;
    font-size: 30px;
  }

  .ql-snow .ql-picker.ql-size .ql-picker-label[data-value="32px"]::before, .ql-snow .ql-picker.ql-size .ql-picker- item[data-value="32px"]::before {<!-- -->
    content: "32px" !important;
    font-size: 32px;
  }

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

  .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" !important;
  }

  .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" !important;
  }

  .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" !important;
  }

  .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" !important;
  }

  .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" !important;
  }

  .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" !important;
  }

  .ql-snow .ql-picker.ql-font .ql-picker-label::before, .ql-snow .ql-picker.ql-font .ql-picker-item::before {<!-- -- >
    content: "standard font" !important;
  }

  .ql-snow .ql-picker.ql-font .ql-picker-label[data-value="serif"]::before, .ql-snow .ql-picker.ql-font .ql-picker- item[data-value="serif"]::before {<!-- -->
    content: "serif font" !important;
  }

  .ql-snow .ql-picker.ql-font .ql-picker-label[data-value="monospace"]::before, .ql-snow .ql-picker.ql-font .ql-picker- item[data-value="monospace"]::before {<!-- -->
    content: "monospaced font" !important;
  }

  .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: "宋体" !important;
    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: "Boldface" !important;
    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" !important;
    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: "楷体" !important;
    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: "Imitation Song" !important;
    font-family: "FangSong";
  }

  .ql-snow .ql-picker.ql-font .ql-picker-label[data-value="Arial"]::before, .ql-snow .ql-picker.ql-font .ql-picker- item[data-value="Arial"]::before {<!-- -->
    content: "Arial" !important;
    font-family: "Arial";
  }

  .ql-snow .ql-picker.ql-font .ql-picker-label[data-value="Times-New-Roman"]::before, .ql-snow .ql-picker.ql-font . ql-picker-item[data-value="Times-New-Roman"]::before {<!-- -->
    content: "Times New Roman" !important;
    font-family: "Times New Roman";
  }

  .ql-snow .ql-picker.ql-font .ql-picker-label[data-value="sans-serif"]::before, .ql-snow .ql-picker.ql-font .ql- picker-item[data-value="sans-serif"]::before {<!-- -->
    content: "sans-serif" !important;
    font-family: "sans-serif";
  }

  .ql-font-SimSun {<!-- -->
    font-family: "SimSun";
  }

  .ql-font-SimHei {<!-- -->
    font-family: "SimHei";
  }

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

  .ql-font-KaiTi {<!-- -->
    font-family: "KaiTi";
  }

  .ql-font-FangSong {<!-- -->
    font-family: "FangSong";
  }

  .ql-font-Arial {<!-- -->
    font-family: "Arial";
  }

  .ql-font-Times-New-Roman {<!-- -->
    font-family: "Times New Roman";
  }

  .ql-font-sans-serif {<!-- -->
    font-family: "sans-serif";
  }

  .ql-snow.ql-toolbar .ql-formats .ql-revoke {<!-- -->
    width: 20px;
    height: 20px;
    filter: grayscale(100%);
    opacity: 1;
  }

  .ql-snow.ql-toolbar .ql-formats .ql-revoke:hover {<!-- -->
    width: 20px;
    height: 20px;
    filter: none;
    opacity: 0.9;
  }

  img {<!-- -->
    filter: grayscale(100%);
    opacity: 1;
  }

  img:hover {<!-- -->
    filter: none;
    opacity: 0.9;
  }

  /*Just add height and scroll attributes. The scroll bar style is the system default style and may be different*/
  .ql-toolbar.ql-snow .ql-picker.ql-expanded .ql-picker-options {<!-- -->
    border-color: #ccc;
    height: 125px;
    overflow: auto;
  }
}

The results are as follows: