React 所见即所得编辑器 Vditor

news/2024/7/15 17:33:10 标签: 编辑器, react.js, javascript

前言

在网页上嵌入一个 Typora 编辑器是不是很酷的一件事?

Markdown是程序员写文档最喜欢的语法,但是直接写Markdown并不够直观,所以出现了「所见即所得」的Markdown编辑器,Typora就是拔尖的产品。

我的博客写作过程是先在 Typora上写好,然后复制Markdown到博客编辑上进行保存发布。开始使用Markdown编辑器是 for-editor,我之前写过for-editor富文本组件的使用方法 React富文本——markdown编辑器

但是这个过程太麻烦了,如果有一个富文本组件能够实现 Markdown所击即所得的编辑文章,那就完美了。

经过在 GitHub 上搜索,发现了类似的富文本组件 Vditor

成品图

image-20211212151508251

安装依赖

NPM

npm install vditor --save

UMD

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/vditor/dist/index.css" />
<script src="https://cdn.jsdelivr.net/npm/vditor/dist/index.min.js"></script>

初始化编辑器

import React, { useEffect, useRef } from 'react';
import Vditor from 'vditor';
import "vditor/dist/index.css";
import './index.less';

interface MarkdownEditorProps {
    value: string;
    onChange: (value: string) => void;
}

export default function MarkdownEditor(props: MarkdownEditorProps) {
    const { value, onChange } = props;
    const editorRef = useRef<HTMLDivElement>(null);

    useEffect(() => {
        const vditor = new Vditor(editorRef.current,
            {
                value,
                input: (value) => onChange(value),
                cache: { id: 'vditor' },
                height: '100%',
                counter: { enable: true }
            })
    }, [])


    return (
        <div className="markdown-editor" ref={editorRef}>

        </div>
    )
}

vditor示例图

image-20211212151508251

对比之前我使用的纯Markdown编辑器for-editor,如果想使用for-editor编辑器,可以参考:React富文本——markdown编辑器

for-editor示例图

image-20211212151718398

vditor详细配置

Vditor官网地址

image-20211212152854879

附件上传功能

配置config

image-20211212153150791
javascript">   let vditor = new Vditor(editorRef.current,
            {
                value,
                input: onChange,
                cache: { id: 'vditor' },
                height: '100%',
                counter: { enable: true },
                // outline: { enable: true, position: 'right' },
                upload: {
                    url: 'http://localhost:300/upload',
                    fieldName: 'file',
                    extraData: { packet: 'blog' },
                    format: (files: File[], responseTxt) => {
                        const res = JSON.parse(responseTxt);
                        const name = files[0].name;
                        const url = res.data.url;
                        const result = JSON.stringify({ code: 0, data: { errFiles: '', succMap: { [name]: url } } });
                        return result;
                    },
                }
            })

一、默认流程

  • 采用vditor默认上传流程,upload必填参数

    • url 填写处理上传服务器地址

    • fieldName 是服务器接受附件参数的字段

    • extraData 除了附件参数外额外的参数

    • format 方法讲服务器返回值格式化成vditor接受的数据格式(JSON格式)

      { code: 0, data: { errFiles: ‘’, succMap: { [name]: url } } }

二、自定义上传

  • 通过 handler 方法处理上传过程,接受 File 参数,返回vditor接受的数据格式

    { code: 0, data: { errFiles: ‘’, succMap: { [name]: url } } }

三、服务器处理

koa

ajax图片上传功能实现(点击,拖拽,粘贴)Koa服务端

Nest

import {
  Post,
  UseInterceptors,
  UploadedFile,
} from '@nestjs/common';

@Post('upload')
  @UseInterceptors(FileInterceptor('file'))
  async smmsCommon(@UploadedFile() file, @Body() body) {
    const { packet } = body;

    const random = uuidv4().replace(/-/g, '');
    const prefix = file.originalname.split('.').pop().toLowerCase();
    const targeName = `${random}.${prefix}`;
    
    ...
    	
    return {code:0,data:'http://localhost:3000/image.png'}
}

http://www.niftyadmin.cn/n/1143006.html

相关文章

python列表的嵌套_Python-嵌套列表list的全面解析

Python-嵌套列表list的全面解析 一个3层嵌套列表m m["a",["b","c",["inner"]]] 需要解析为基本的数据项a,b,c,inner 基本的取数据项方法&#xff1a; for i in m: print i这个只能取出第一层的a,和一个2层的嵌套列表["b",&q…

【Typescript】paths alias别名设置

前言 Typescript 不仅方便前端在开发阶段就能发现很多问题&#xff0c;同时也能给开发者很多提示。比如我们 Import 其他ESModule时&#xff0c;如果路径不对就会给出提示。 只有正确引用路径&#xff0c;Typescript才不会提示报错。但是使用这种相对路径引用方式&#xff0c;…

电商库存锁_手写AQS锁解决秒杀超卖

业务场景电商活动的秒杀场景&#xff0c;在并发过来的时候很容易出现库存扣超的情况&#xff0c;一个很简单的例子是&#xff0c;两个线程同时拿到了库存为1的数据&#xff0c;同时扣减库存&#xff0c;那么库存就会变为负的。所以要解决这个问题还是要让请求串行&#xff0c;串…

windows api message box_如何在windows系统上安装Tensorflow Object Detection API?

前言都说Linux是最适合程序员使用的操作系统&#xff0c;这话还真不假。之前一直在云服务器上跑代码&#xff0c;近期接手了师兄的台式机(GTX 1050)&#xff0c;虽然配置很渣&#xff0c;但想在本地玩玩看&#xff0c;于是乎先安装一波Tensorflow Object Detection API。之前云…

【Rollup】自定义组件 - 文章渲染组件

前言 利用 Rollup 构建一个文章展示抽屉SDK&#xff0c;用来记录前端自定义SDK的过程 工程实践 初始化 创建项目 mkdir packageName npm init -yTypescript功能初始化 npm install typescript -Dnpx tsc -init创建 rollup.config.js import typescript from rollup-plu…

gson 不忽略空_儿童房都用高低床?它不一定适合你娃!

现在很多九零后、八零后的爸爸妈妈都开始有了二胎计划&#xff0c;对于儿童房的装修可以说是用尽了心思&#xff0c;很多人都会选择高低床&#xff0c;来解决空间有限的问题。不过对于高低床每个人都有着自己的观点——有的人觉得非常实用&#xff0c;有的人则觉得不太安全&…

tcp转websocket_WebSocket与普通Socket的差异

1.背景1.1.WebSocket与普通Socket的差异Socket简单理解&#xff1a;Socket IP地址 端口 协议。具体来说&#xff0c;Socket是一套标准&#xff0c;它完成了对TCP/IP的高度封装&#xff0c;屏蔽网络细节以方便开发者更好地进行网络编程。Socket有自己的原语。WebSocketWebSoc…

实现一个Switch开关组件只需要一个div?详细记录Switch组件开发过程

最终效果图 实现逻辑 一、switch容器 // html<div className"dumbo-switch"></div>// css.dumbo-switch {height: 22px;width: 44px;border: 1px solid;border-radius: 100px;border: 1px solid #cccccc;cursor: pointer;}二、switch inner // html// c…