markdown编辑器-Bytemd使用

2,724 阅读2分钟

前言✨

在开发博客的时候想找一个颜值、功能都强大的markdown编辑器,看了CSDN觉得ui太丑,看了简书的又感觉功能不够强大,然后看了掘金的编辑器感觉非常符合我的气质,后来去查了一下掘金用的编辑器叫Bytemd

ByteMD 是一个使用 Svelte 构建的 Markdown 编辑器组件。它也可以用于其他库/框架,例如 ReactVueAngular,是字节跳动团队开发维护的开源项目。

gitHub:github.com/bytedance/b…

官方示例bytemd.netlify.app/

安装⚙

可以看到他有三个版本,由于我的博客是react开发的所以我需要安装@bytemd/react image.png

$ yarn add @bytemd/react

插件介绍及使用💻

Bytemd目前有多种插件来增强优化markdown的能力如下:

image.png

首先要引入所需插件

import zhHans from 'bytemd/lib/locales/zh_Hans.json';// 中文插件
import gfm from '@bytemd/plugin-gfm';// 支持GFM
import highlight from '@bytemd/plugin-highlight';// 代码高亮
import 'highlight.js/styles/monokai-sublime.css';// 代码高亮的主题样式(可自选)
import frontmatter from '@bytemd/plugin-frontmatter';// 解析前题
import mediumZoom from '@bytemd/plugin-medium-zoom';// 缩放图片

定义插件

const plugins = [
  gfm(), // GFM
  highlight(), // 代码高亮
  frontmatter(), // 解析前题
  mediumZoom(), // 图片缩放
  gemoji() // Gemoji短代码
];

在bytemd中使用

 <Editor
    locale={zhHans}
    plugins={plugins}
    value={props.value}
    onChange={(v) => props.setValue(v)}
  />

增加图片上传功能🎨

image.png uploadImages使用方法,需要return出数组

import { uploadImg } from '@/services/upload';// 接口地址
<Editor
    value={props.value}
    onChange={(v) => props.setValue(v)}
    uploadImages={async (files: any) => {
      let imgUrl = '';
      let fromData = new FormData();
      fromData.append('uploadImg', files[0]);
      const res = await uploadImg(fromData);
      if (res.code === 200) {
        imgUrl = res.data;// 这里是上传成功后,服务端返回的图片地址
      } else {
        console.log(图片上传失败)
      }
      return [
        {
          title: files.map((i) => i.name),
          url: imgUrl,
        },
      ];
    }}
  />

封装成react组件及使用🎈

封装index.tsx (完整代码)

import React from 'react';
import { Editor } from '@bytemd/react';
import zhHans from 'bytemd/lib/locales/zh_Hans.json';// 中文插件
import gfm from '@bytemd/plugin-gfm';// 支持GFM
import highlight from '@bytemd/plugin-highlight';// 代码高亮
import 'highlight.js/styles/monokai-sublime.css';// 代码高亮的主题样式(可自选)
import frontmatter from '@bytemd/plugin-frontmatter';// 解析前题
import mediumZoom from '@bytemd/plugin-medium-zoom';// 缩放图片
import { uploadImg } from '@/services/upload';
import { notification } from 'antd';
import 'bytemd/dist/index.min.css';// bytemd基础样式必须引入!!!
import 'juejin-markdown-themes/dist/juejin.min.css';// 掘金同款样式
interface EditorProps {
  value: string;
  setValue: any;
}
const plugins = [
  gfm(), // GFM
  highlight(), // 代码高亮
  frontmatter(), // 解析前题
  mediumZoom(), // 图片缩放
  gemoji(), // Gemoji短代码
];
const Bytemd: React.FC<EditorProps> = (props) => {
  return (
    <>
      <Editor
        locale={zhHans}
        plugins={plugins}
        value={props.value}
        onChange={(v) => props.setValue(v)}
        uploadImages={async (files: any) => {
          let imgUrl = '';
          let fromData = new FormData();
          fromData.append('uploadImg', files[0]);
          const res = await uploadImg(fromData);
          if (res && res.code === 200) {
            imgUrl = res.data;// 这里是上传成功后,服务端返回的图片地址
          } else {
            notification.error({
              message: '图片上传失败',
            });
          }
          return [
            {
              title: files.map((i) => i.name),
              url: imgUrl,
            },
          ];
        }}
      />
    </>
  );
};
export default Bytemd;

使用方式,articleDetail.tsx (精简代码)

import React, { useEffect, useState } from 'react';
import Bytemd from '@/components/Bytemd';// 引入组件
import {getArticleDetail } from '@/services/article';// 引入请求接口
const ArticleDetail: React.FC = () => {
 // 单独存取markdown值,因为我们不仅有新增还有编辑文章的场景
  const [value, setValue] = useState<string>('');
    useEffect(() => {
      getDetail();
    }, []);
   // 获取数据
   const getDetail = async () => {
    const res = await getArticleDetail({ id: query.id as string });
    if (res.code === 200) {
      setValue(res.data.content);// 赋值
    }
  };
  return (
       <Bytemd value={value || ''} setValue={setValue} />
  )
}
export default ArticleDetail;