1 Introduction
The existing Quill is relatively simple and cannot meet business needs (such as SEO image attribute editing requirements).
Quill has not been updated for a long time. Although it is very flexible, there is no official demo.
In the early stage of the business, there was no need for this area, and the expansion of this area was not considered.
Comparison of common rich text editors on the market:
- Open source rich text editor comparison
- A comparison of common rich text editors
found that many people do not recommend quill very much. (To be honest, I don’t recommend it very much. Your official demo doesn’t even have a rich text editor. Are you going to heaven?)
2. Getting started with the official website
Official website address
Official website introduction
(Just look at it, basically the same)
For Vue React | wangEditor
Just find the corresponding Vue version directly. If React is useful, you can also use it (I didn’t use it)
Official website demo
The official provides an online version, which can be directly edited and tried online. If the network is not good, you can also download the code to local processing.
Demo code online running address
Install wangEditor
npm install @wangeditor/editor --save # 或者 yarn add @wangeditor/editor
npm install @wangeditor/editor-for-vue --save # 或者 yarn add @wangeditor/editor-for-vue
Note: 1. Please check whether your corresponding Vue version is Vue2 or Vue3 before installation.
2. There may often be version conflicts. If there is a version problem, please add the npm installation parameter --legacy-peer-deps (for details, please use Baidu)
3. Basic configuration items
(1) Component reference
<template>
<div>
<div style="border: 1px solid #ccc; margin-top: 10px">
<!-- 工具栏 -->
<Toolbar
style="border-bottom: 1px solid #ccc"
:editor="editor"
:defaultConfig="toolbarConfig"
/>
<!-- 编辑器 -->
<Editor
style="height: 400px; overflow-y: hidden"
:defaultConfig="editorConfig"
v-model="html"
@onChange="onChange"
@onCreated="onCreated"
/>
</div>
</div>
</template>
(2) Default configuration items
<script>
import {
Editor, Toolbar } from "@wangeditor/editor-for-vue";
import "@wangeditor/editor/dist/css/style.css";
export default {
name: "MyEditor",
components: {
Editor, Toolbar },
data() {
return {
editor: null,
html: "<p>hello world</p>",
toolbarConfig: {
// toolbarKeys: [ /* 显示哪些菜单,如何排序、分组 */ ],
// excludeKeys: [ /* 隐藏哪些菜单 */ ],
},
editorConfig: {
placeholder: "请输入内容...",
// autoFocus: false,
// 所有的菜单配置,都要在 MENU_CONF 属性下
MENU_CONF: {
},
},
};
},
methods: {
onCreated(editor) {
// 【注意】一定要用 Object.seal() 否则会报错
this.editor = Object.seal(editor);
}
},
mounted() {
// 模拟 ajax 请求,异步渲染编辑器
setTimeout(() => {
this.html = "<p>Ajax 异步设置内容 HTML</p>";
}, 1500);
},
beforeDestroy() {
const editor = this.editor;
if (editor == null) return;
editor.destroy(); // 组件销毁时,及时销毁 editor ,重要!!!
},
};
</script>
The basic configuration is OK.
Basically run to see the box below.
4. Personalized parameter configuration
Upload and call background interface configuration
The frame comes out, and you find that uploading pictures will prompt the following error:
the reason is that the upload path address needs to be configured.
According to the official statement, you can directly configure the corresponding parameters
- The official upload image portal
can refer to the official demo - Upload picturesOfficial Demo
editorConfig: {
//菜单配置
MENU_CONF: {
// 配置上传图片
uploadImage: {
//server必须要配置正确
server: '/api/upload',
...
}
}
}
More menu configuration
Please check the menu configuration
Personal menu configuration content
editorConfig: {
placeholder: "请输入内容...",
pasteFilterStyle: false,
zIndex: 12000,
//看这里
//-----------------------------------
MENU_CONF: {
// 配置上传图片
uploadImage: {
//server必须配置
server: process.env.VUE_APP_API_BASE_URL + "/api/upload",
// 最多可上传几个文件,默认为 100
maxNumberOfFiles: 10,
// 选择文件时的类型限制,默认为 ['image/*'] 。如不想限制,则设置为 []
allowedFileTypes: [],
// 自定义上传参数,例如传递验证的 token 等。参数会被添加到 formData 中,一起上传到服务端。
fieldName: "file",
meta: {
//官网中把token放到了这里,但是请求的时候会看不到token
},
headers: {
//token放这里 getUserToken()这个方法需要自己实现
Authorization: "Bearer " + getUserToken(),
},
// 将 meta 拼接到 url 参数中,默认 false
metaWithUrl: false,
// 跨域是否传递 cookie ,默认为 false
withCredentials: false,
// 超时时间,默认为 10 秒
timeout: 5 * 1000, // 5 秒
customInsert(res, insertFn) {
// 从 res 中找到 url alt href ,然后插图图片
// res 是上传后,从后端返回的结果集。具体根据返回对象进行设置。
if(res.code===200){
const imageObj=res.data[0]
insertFn(imageObj.url, imageObj.name, imageObj.url)
}
},
},
},
mode:"default",// "simple",
}
editor configuration
Toolbar configuration
Other common functions
Sometimes it is necessary to clear the historical data, which is mainly for the convenience of reassignment.
Clear() method to reset
- The this.editor.clear() method can clear the editor content.
- this.editor.setHtml() sets the content.
5. Basic style adjustment
(1) Adding borders
Style adjustments are a little blurry, so you need to position them slowly.
The outermost style is as follows:
style="border: 1px solid #1890ff"
The outermost layer includes two components, Toolbar and Editor.
(2) Adjust the picture editing box
The style of the picture is not highlighted by default. If you need to highlight, you need to adjust the current style.
code show as below:
.editor >>> .w-e-text-container{
.w-e-hover-bar{
/* 选中图片样式样式覆盖*/
border: 1px solid #1890ff;
color: #1890ff;
}
.w-e-modal {
/* 弹框边框样式覆盖 */
border: 1px solid #1890ff;
}
.w-e-modal button {
/* 弹框按钮样式覆盖 */
background-color: #1890ff;
color: #fff;
}
}
6. Code
The whole code is as follows:
- editor configuration parameters:
<template>
<div>
<div style="border: 1px solid #ccc; margin-top: 10px">
<!-- 工具栏 -->
<Toolbar
style="border-bottom: 1px solid #ccc"
:editor="editor"
:defaultConfig="toolbarConfig"
/>
<!-- 编辑器 -->
<Editor
style="height: 400px; overflow-y: hidden"
:defaultConfig="editorConfig"
v-model="html"
@onChange="onChange"
@onCreated="onCreated"
/>
</div>
</div>
</template>
<script>
import {
Editor, Toolbar } from "@wangeditor/editor-for-vue";
export default {
name: "MyEditor",
components: {
Editor, Toolbar },
data() {
return {
editor: null,
html: "<p>hello world</p>",
toolbarConfig: {
// toolbarKeys: [ /* 显示哪些菜单,如何排序、分组 */ ],
// excludeKeys: [ /* 隐藏哪些菜单 */ ],
},
editorConfig: {
place
holder: "请输入内容...",
pasteFilterStyle: false,
zIndex: 12000,
//看这里
//-----------------------------------
MENU_CONF: {
// 配置上传图片
uploadImage: {
//server必须配置
server: process.env.VUE_APP_API_BASE_URL + "/api/upload",
// 最多可上传几个文件,默认为 100
maxNumberOfFiles: 10,
// 选择文件时的类型限制,默认为 ['image/*'] 。如不想限制,则设置为 []
allowedFileTypes: [],
// 自定义上传参数,例如传递验证的 token 等。参数会被添加到 formData 中,一起上传到服务端。
fieldName: "file",
meta: {
//官网中把token放到了这里,但是请求的时候会看不到token
},
headers: {
//token放这里 getUserToken()这个方法需要自己实现
Authorization: "Bearer " + getUserToken(),
},
// 将 meta 拼接到 url 参数中,默认 false
metaWithUrl: false,
// 跨域是否传递 cookie ,默认为 false
withCredentials: false,
// 超时时间,默认为 10 秒
timeout: 5 * 1000, // 5 秒
customInsert(res, insertFn) {
// 从 res 中找到 url alt href ,然后插图图片
// res 是上传后,从后端返回的结果集。具体根据返回对象进行设置。
if(res.code===200){
const imageObj=res.data[0]
insertFn(imageObj.url, imageObj.name, imageObj.url)
}
},
},
},
mode:"default",// "simple",
}
};
},
methods: {
onCreated(editor) {
this.editor = Object.seal(editor); // 【注意】一定要用 Object.seal() 否则会报错
},
},
mounted() {
// 模拟 ajax 请求,异步渲染编辑器
setTimeout(() => {
this.html = "<p>Ajax 异步设置内容 HTML</p>";
}, 1500);
},
beforeDestroy() {
const editor = this.editor;
if (editor == null) return;
editor.destroy(); // 组件销毁时,及时销毁 editor ,重要!!!
},
};
</script>
7. Summary
(1) Generally speaking, it is relatively simple
(2) It is necessary to pay attention to the settings of personalization
① Personalization, there are official instructions, but the examples are not obvious. I need to try one by one by myself.
There is a little bug (but I can bear it).
If the picture is too large, the property box will not be displayed due to the direct selection of the picture
ps:editor.destroy(); // When the component is destroyed, it is important to destroy the editor in time! ! ! When the window pops up, it is best to destroy all subcomponents. In this way, it will not cause the problem of not echoing after clicking multiple times.