好用的 Markdown 编辑器组件

ByteMD

bytedance/bytemd: ByteMD v1 repository (github.com)

这里由于我的项目是 Next,所以安装 @bytemd/react, 阅读官方文档,执行命令来安装编辑器主体、以及 gfm(表格支持)插件、highlight 代码高亮插件:

shell 复制代码
npm i @bytemd/react
npm i @bytemd/plugin-highlight @bytemd/plugin-gfm

但是浏览器的样式不好看,我们可以引入第三方主题:
github-markdown-css

shell 复制代码
npm install github-markdown-css
import 'github-markdown-css/github-markdown-light.css';

然后使用组件:

src/components/MdEditor/index.tsx

tsx 复制代码
import { Editor } from "@bytemd/react";
import gfm from "@bytemd/plugin-gfm";
import highlight from "@bytemd/plugin-highlight";
import 'github-markdown-css/github-markdown-light.css';
import "bytemd/dist/index.css";
import "highlight.js/styles/vs.css";
import "./index.css";

interface Props {
    value?: string;
    onChange?: (v: string) => void;
    placeholder?: string;
}

const plugins = [gfm(), highlight()];

/**
 * Markdown 编辑器
 * @param props
 * @constructor
 */
const MdEditor = (props: Props) => {
    const { value = "", onChange, placeholder } = props;

    return (
        <div className="md-editor">
            <Editor
                value={value || ""}
                placeholder={placeholder}
                mode="split"
                plugins={plugins}
                onChange={onChange}
            />
        </div>
    );
};

export default MdEditor;

把 MdEditor 当前输入的值暴露给父组件,便于父组件去使用,同时也是提高组件的通用性,所以定义了属性和属性类型,把 value 和 onChange 事件交给父组件去管理。

src/components/MdEditor/index.css

css 复制代码
.md-editor {
    .bytemd-toolbar-icon.bytemd-tippy.bytemd-tippy-right:last-child {
        display: none;
    }
}

隐藏编辑器中不需要的操作图标(像 GitHub 图标)

编辑好文本,自然有浏览文本的地方,所以浏览器:

src/components/MdViewer/index.tsx

tsx 复制代码
import { Viewer } from "@bytemd/react";
import gfm from "@bytemd/plugin-gfm";
import highlight from "@bytemd/plugin-highlight";
import 'github-markdown-css/github-markdown-light.css';
import "bytemd/dist/index.css";
import "highlight.js/styles/vs.css";
import "./index.css";

interface Props {
    value?: string;
}

const plugins = [gfm(), highlight()];

/**
 * Markdown 浏览器
 * @param props
 * @constructor
 */
const MdViewer = (props: Props) => {
    const { value = "" } = props;

    return (
        <div className="md-viewer">
            <Viewer value={value} plugins={plugins} />
        </div>
    );
};

export default MdViewer;

src/components/MdViewer/index.css

css 复制代码
.md-viewer {
    .bytemd-toolbar-icon.bytemd-tippy.bytemd-tippy-right:last-child {
        display: none;
    }
}

可以在任意客户端渲染页面(或组件)引入组件进行测试,这是因为该组件用到了 useRef 之类的仅客户端才支持的函数。

tsx 复制代码
const [text, setText] = useState<string>('');

<MdEditor value={text} onChange={setText} />
<MdViewer value={text} />

md-editor-v3

文本编辑器/md-editor-v3 (gitee.com)

这个是之前写 Vue3 用过的一个编辑器,也很不错,用法简单,同样支持 Vue、React 等。

安装

yarn add md-editor-v3

更多使用及贡献方式参考:md-editor-extension

编辑器模式

vue 复制代码
<template>
  <MdEditor v-model="text" />
</template>

<script setup>
import { ref } from 'vue';
import { MdEditor } from 'md-editor-v3';
import 'md-editor-v3/lib/style.css';

const text = ref('# Hello Editor');
</script>

仅预览模式

vue 复制代码
<template>
  <MdPreview :editorId="id" :modelValue="text" />
  <MdCatalog :editorId="id" :scrollElement="scrollElement" />
</template>

<script setup>
import { ref } from 'vue';
import { MdPreview, MdCatalog } from 'md-editor-v3';
import 'md-editor-v3/lib/preview.css';

const id = 'preview-only';
const text = ref('# Hello Editor');
const scrollElement = document.documentElement;
</script>
相关推荐
慢慢雨夜22 分钟前
uniapp 苹果安全域适配
java·前端·uni-app
凄凄迷人25 分钟前
前端基于Rust实现的Wasm进行图片压缩的技术文档
前端·rust·wasm·图片压缩
敲代码不忘补水28 分钟前
二十种编程语言庆祝中秋节
java·javascript·python·golang·html
我码玄黄34 分钟前
JS 的行为设计模式:策略、观察者与命令模式
javascript·设计模式·命令模式
史努比的大头40 分钟前
前端开发深入了解性能优化
前端
码农研究僧41 分钟前
Java或者前端 实现中文排序(调API的Demo)
java·前端·localecompare·中文排序·collator
营赢盈英1 小时前
OpenAI API key not working in my React App
javascript·ai·openai·reactjs·chatbot
guigui_hello1 小时前
VScode的简单使用
c++·ide·vscode·编辑器
吕永强1 小时前
HTML表单标签
前端·html·表单标签