2023-03-08
前端
00

目录

📖阅读本文,您将收获
一、markdown编辑器的槽点
二、新宠儿:Milkdown
2.1 安装并运行
2.2 顶部工具栏插件
2.3 复制粘贴插件
2.4 选择工具栏插件
2.5 支持/ 命令插件
2.6 设置默认内容及添加事件插件
三、结束语

IMG_0406.HEIC.JPG

📖阅读本文,您将收获

  • 了解到优秀的markdown产品wolainotion
  • markdown编辑器选型,多一个选择项
  • 学会如何使用Mildown

一、markdown编辑器的槽点

作为研发人员,我不相信您编写文档没有使用过markdown;如果使用markdown编写文档,那肯定是离不开一款markdown编辑器。

但是呢,市面上markdown编辑器又有蛮多槽点的:

  • 大部分开源编辑器,它是编辑区与预览区分离 image.png 上图为掘金平台使用的编辑器,编辑区与预览区分离老碍眼了。古板,我觉得两者结合做到所见即所得会更好。

  • 收费

    做到所见即所得的markdown编辑器,当然有,例如市面上的Typorawolainotion

    这三款编辑器产品,用过的人都说好,强烈推荐

    它们有个共同的问题:商业化,商业化的产品目的就是搞钱,所以呢,它们有部分高级功能是需要付费的。

    但对大部分无特殊功能要求的人,它们已经够用了。

  • 不开源

    Typorawolainotion产品,它们的源代码是没有开放出来的,我们想在项目中集成它们是不可能的。

二、新宠儿:Milkdown

GitHub Star数: 6k+

Milkdown是什么?

官方自我介绍:

Milkdown 是一个轻量但强大的 WYSIWYG(所见即所得)的 markdown 编辑器

为什么选择Milkdown?

官方理由:

  • 为开发者提供一个免费开源解决方案
  • 不同于 NotionTypora 等商用软件,Milkdown是开源且永久免费的
  • 值得信赖,有强大的社区支撑

image.png

在线体验:https://milkdown.dev/zh-hans/online-demo

GitHub: https://github.com/Saul-Mirone/milkdown

2.1 安装并运行

Mildown以插件驱动,它由核心模块、官方插件组成。

安装核心模块:

npm i @milkdown/core @milkdown/transformer @milkdown/prose @milkdown/ctx

创建Editor实例:

import { Editor } from "@milkdown/core" Editor.make().create()

执行,两行代码就报错啦!!

  • 错误1:Uncaught (in promise) Timing InitReady timeout.

    原因是缺少主题,再安装一个主题包:

npm i @milkdown/theme-nord
import { Editor } from "@milkdown/core" import { nord } from "@milkdown/theme-nord" Editor.make().use(nord).create()
再次运行,紧接着第二个报错出现。
  • 错误2:Uncaught (in promise) RangeError: Schema is missing its top node type ('doc')

    错误大概意思是缺少doc节点,这是原因缺少markdown预设指令插件。

    官方提供了两款插件:@milkdown/preset-commonmark、@milkdown/preset-gfm,推荐@milkdown/preset-gfm

    同样的,下载使用:

import { Editor } from "@milkdown/core" import { nord } from "@milkdown/theme-nord" import {gfm} from "@milkdown/preset-gfm" Editor.make().use(nord).use(gfm).create()

Aug-14-2022 11-37-41.gif 至此,Milkdown成功运行。接下来,只需要按需添加插件。

2.2 顶部工具栏插件

npm i @milkdown/plugin-menu

还是链式调用use ,注册插件。

import { Editor } from "@milkdown/core" import { nord } from "@milkdown/theme-nord" import { gfm } from "@milkdown/preset-gfm" // 工具栏 import { menu } from '@milkdown/plugin-menu'; Editor .make() .use(nord) .use(gfm) .use(menu) .create()

但得到的是一堆英文单词:

image.png

功能是存在的,但展示有问题,需要把一堆英文单词替换成字体图标。

import { Editor ,ThemeIcon} from "@milkdown/core" import { nord } from "@milkdown/theme-nord" import { gfm } from "@milkdown/preset-gfm" // 工具栏 import { menu } from '@milkdown/plugin-menu'; import { getIcon } from "./icon" Editor .make() .use(nord.override((emotion, manager) => { manager.set(ThemeIcon, (icon) => { if (!icon) return; return getIcon(icon); }); })) .use(gfm) .use(menu) .create()

针对@milkdown/theme-nord 设置,添加一个getIcon 方法。

icon 文件内容过多此处不粘贴,请移动GitHub阅读:https://github.com/CatsAndMice/milkdown/blob/master/icon.js

另外需要加载字体图标资源:

<html> //... <link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons" /> </html>

image.png

2.3 复制粘贴插件

import { clipboard } from '@milkdown/plugin-clipboard';
//... import { clipboard } from '@milkdown/plugin-clipboard'; Editor .make() .use(nord.override((emotion, manager) => { manager.set(ThemeIcon, (icon) => { if (!icon) return; return getIcon(icon); }); })) .use(gfm) .use(menu) .use(clipboard) .create()

2.4 选择工具栏插件

npm i @milkdown/plugin-tooltip

设置工具栏选中后置顶:

//... import { tooltipPlugin, tooltip } from '@milkdown/plugin-tooltip'; Editor .make() .use(nord.override((emotion, manager) => { manager.set(ThemeIcon, (icon) => { if (!icon) return; return getIcon(icon); }); })) .use(gfm) .use(menu) //新增 .use(tooltip.configure(tooltipPlugin, { top: true, })) .create()

image.png

2.5 支持/ 命令插件

npm i @milkdown/plugin-slash

输入/,自定义添加面板功能配置:

import { defaultValueCtx, Editor, rootCtx, ThemeIcon, themeManagerCtx } from "@milkdown/core"; //... import {slash,createDropdownItem,defaultActions,slashPlugin} from '@milkdown/plugin-slash'; Editor .make() // 新增 .use(slash.configure(slashPlugin, { config: (ctx) => { return ({ content, isTopLevel }) => { if (!isTopLevel) return null; if (!content) { return { placeholder: "键入文字或'/'选择" }; } const mapActions = (action) => { const { id = "" } = action; switch (id) { case "h1": action.dom = createDropdownItem( ctx.get(themeManagerCtx), "标题1", "h1" ); return action; //... default: return action; } }; if (content.startsWith("/")) { return content === "/" ? { placeholder: " ", actions: defaultActions(ctx).map(mapActions) } : { actions: defaultActions(ctx, content).map(mapActions) }; } return null; }; } }))

image.png

2.6 设置默认内容及添加事件插件

设置默认内容是核心模块提供的功能,不必安装插件。

import { defaultValueCtx, Editor, rootCtx, ThemeIcon, themeManagerCtx } from "@milkdown/core"; //... Editor.make() .config((ctx) => { ctx.set(rootCtx, document.querySelector('#app')); ctx.set(defaultValueCtx, "## 点赞+评论+关注=学会"); }) //...

添加事件:

npm i @milkdown/plugin-listener

@milkdown/plugin-listener分别对应七个生命周期函数:

事件名事件描述
beforeMount挂载前
mounted挂载后
updated状态更新
markdownUpdatedmarkdown 更新
blur失焦
focus聚焦
destroy销毁
//... import { listenerCtx, listener } from "@milkdown/plugin-listener" Editor.make() .config((ctx) => { ctx.set(rootCtx, document.querySelector('#app')); ctx.set(defaultValueCtx, "## 点赞+评论+关注=学会"); //新增 ctx.get(listenerCtx).markdownUpdated((ctx, markdown, prevMarkdown) => { console.log(markdown); }); }) //...

借助上述事件,可以自定义获取内容等功能。

Milkdown官方还有其他功能插件,例如:图片上传等,文章不逐一列举了。

文章演示代码已开放GitHub: https://github.com/CatsAndMice/milkdown

三、结束语

原创不易!如果我的文章对你有帮助,点赞+评论+关注就是对我的最大支持^_^。

本文作者:凌览

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!