Preliminary study on rich text editor wangEditor

insert image description here

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:

2. Getting started with the official website

Official website address

Official website address

Official website introduction

(Just look at it, basically the same)
Official website introduction

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&nbsp;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.
insert image description here

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:
insert image description here
the reason is that the upload path address needs to be configured.

According to the official statement, you can directly configure the corresponding parameters

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

editor configuration

Toolbar 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&nbsp;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.

Guess you like

Origin blog.csdn.net/m290345792/article/details/131954084