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