Vue-quill-editor solves the problem that the data returned by the backend cannot be displayed normally

At first, I wanted to find a rich text editor used in vue3. I searched on Baidu and found vue-quill-editor. I didn’t expect to encounter so many pitfalls.

Some websites about vue-quill-editor seem to have similar configurations.

API – Quill Rich Text Editor

Configuration Items – Quill Documentation

Formatting Quill Official Chinese Documentation Kanyun

First download and install it in the terminal, and it must be installed in the corresponding front-end folder.

npm install @vueup/vue-quill@alpha --save

Secondly, it is also possible to register as a global component in the main.js file, or as a local component in the corresponding vue file.

import { createApp } from 'vue'
// import component
import { QuillEditor } from '@vueup/vue-quill'
// Import the corresponding style file, I only use the theme of snow here
import '@vueup/vue-quill/dist/vue-quill.snow.css';

// There are two other theme styles
// import '@vueup/vue-quill/dist/vue-quill.core.css';
// import '@vueup/vue-quill/dist/vue-quill.bubble.css';

// Import the css style of the message in the element-plus component library, and the message on the corresponding page will be displayed normally
import 'element-plus/theme-chalk/el-message.css'
const app = createApp(App)
// mount as a global component, or register as a local component in the corresponding vue file
app.component('QuillEditor', QuillEditor).use(router).mount('#app')

After registering as a global component, it can be used in the corresponding folder, and there will be a `quill-editor` label globally. Can be used directly in vue files. I don’t want to make it too complicated, you just need to look at the corresponding code. The most important thing here is to use ref to get the native dom element of the quill-editor tag, and use the quillRef.value.setHTML(data.content) method to set the data returned by the backend to the native dom of the quill-editor tag.

I don’t know why, the data obtained by console.log(ruleForm.content, data.content) in the fetch method is indeed the data obtained from the backend, but :content=”ruleForm.content” did not take effect, so I tried for a long time , Now I only know that using the setHTML method is successful. If there are brothers who have other methods, please let me know in the comment area, thank you.

<template>
   <quill-editor
              ref="quillRef"
              content-type="html"
              style="width: 1008px"
              theme="snow"
              class="editor"
              :content='ruleForm.content'
              :options='option'>
 </quill-editor>

   <el-button type="primary" style="margin-top:50px" @click="submitForm()">Save</el-button>
     
</template>

<script setup>
import {reactive, toRaw, ref} from "vue";
import {useRouter} from 'vue-router'
import {ElMessage} from 'element-plus'
const router = useRouter()

// Get the native dom tag of the quill-editor tag.
let quillRef=ref(null)

let ruleForm = reactive({
  title: '',
  categories: [],
  content: ''
})

// option is a configuration item
const option=reactive({
    modules: {
      toolbar: [
        [{ header: [1, 2, 3, 4, 5, 6, false] }], // header
        ['bold', 'italic', 'underline', 'strike'], // bold italic underline strikethrough
        [{ color: [] }, { background: [] }], // font color, font background color
        [{ align: [] }], // alignment
        [{ font: [] }], // font type
        [{ direction: 'rtl' }], // text direction
        [{ indent: '-1' }, { indent: ' + 1' }], // indentation
        [{ list: 'ordered' }, { list: 'bullet' }], // ordered and unordered lists
        [{ script: 'sub' }, { script: 'super' }], // superscript/subscript
        ['blockquote', 'code-block'], // quote code block
        ['clean'], // clear text formatting
        ['link', 'image', 'video'] // link, image, video
        ]
    }
  })

// The logic here is that if there is an id attribute, then edit the article, send a request to the backend, and edit the ruleForm according to the corresponding id
//Good article titles, categories and contents are converted to ordinary objects with toRaw and sent to the backend, which are stored in the database. If there is no id field,
//A new article will be created, just convert the ruleForm into a common object and pass it to the backend. Finally, the route navigates to the list page and pops up a message
//success reminder
const submitForm = async () => {
  let res
  if (props. id) {
    res = await changeArticle(props.id, toRaw(ruleForm))
  } else {
    res = await submitArticle(toRaw(ruleForm))
  }
  router.push('/articles/list')
  ElMessage({
    message: 'saved successfully',
    type: 'success',
  })
}

// The meaning of the code is that if there is an id, the fetch method is called, and the classification, title and content are requested from the backend, and then they are assigned to the ruleForm pair
//The corresponding attributes in the image, the most important is quillRef.value.setHTML(data.content) Call this method to set the contents of the content
//The content is set to the data obtained from the backend.
props.id & amp; & amp; fetch()
const fetch = async () => {
  const {data} = await getArticleClassify(props.id)
  ruleForm.title = data.title
  ruleForm.content=data.content
  ruleForm.categories = data.categories
  quillRef.value.setHTML(data.content)

}

</script>

<style scoped>

</style>

options, theme, content-type, content, etc. are all configuration items. options indicates which functions you want to add, theme is the theme, content-type is the format to display, content is the text content, specific information You can click the attribute with the left mouse button and ctrl to enter the corresponding file to view.

import Delta from 'quill-delta';
import { PropType } from 'vue';
import Quill from 'quill';
import { QuillOptionsStatic } from 'quill';
export { Delta }
export { Quill }

export declare const QuillEditor: import("vue").DefineComponent<{
    content: {
        type: PropType<string | Delta>;
        default: {};
    };
    contentType: {
        type: PropType<"delta" | "html" | "text">;
        default: string;
        validator: (value: string) => boolean;
    };
    enable: {
        type: BooleanConstructor;
        default: boolean;
    };
    readOnly: {
        type: BooleanConstructor;
        default: boolean;
    };
    placeholder: {
        type: StringConstructor;
        required: false;
    };
    theme: {
        type: PropType<"" | "snow" | "bubble">;
        default: string;
        validator: (value: string) => boolean;
    };
    toolbar: {
        type: (StringConstructor | ObjectConstructor | ArrayConstructor)[];
        required: false;
        validator: (value: string | unknown) => boolean;
    };
    options: {
        type: PropType<QuillOptionsStatic>;
        required: false;
    };
    globalOptions: {
        type: PropType<QuillOptionsStatic>;
        required: false;
    };
}, {
    editor: import("vue").Ref<Element | undefined>;
    getEditor: () => Element;
    getToolbar: () => Element;
    getQuill: () => Quill;
    getContents: () => string | Delta | undefined;
    setContents: (content: string | Delta) => void;
    getHTML: () => string;
    setHTML: (html: string) => void;
    getText: () => string;
    setText: (text: string) => void;
    reinit: () => void;
}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, ("textChange" | "selectionChange" | "editorChange" | "update:content" | "focus" | "blur" | "ready")[], "textChange" | "selectionChange" | "editorChange" | "update:content" | "focus" | "blur" | "ready", import("vue").VNodeProps & amp; import("vue").AllowedComponentProps & amp; import("vue").ComponentCustomProps, Readonly<{
    content: string | Delta;
    contentType: "delta" | "html" | "text";
    enable: boolean;
    readOnly: boolean;
    theme: "" | "snow" | "bubble";
} & {
    placeholder?: string | undefined;
    toolbar?: unknown;
    options?: QuillOptionsStatic | undefined;
    globalOptions?: QuillOptionsStatic | undefined;
}>, {
    content: string | Delta;
    contentType: "delta" | "html" | "text";
    enable: boolean;
    readOnly: boolean;
    theme: "" | "snow" | "bubble";
}>;

export { }

The objects configured by options are just the icons displayed on the right side of the details in the figure below. You can try how to write the configuration objects at this URL. Interactive Playground – Quill Rich Text Editor

The ordinary object converted from ruleForm is as shown in the figure below

The knowledge points of the article match the official knowledge files, and you can further learn relevant knowledge