前言

之前,一直想开发一款属于自己的Markdown编辑器,主要是自己平常写文章可以更加灵活操作,另外扩宽自己的视野也是非常不错的选择啊!所以在周末就决定玩耍一番。首先我调研了很多线上热门的md编辑器,都很优秀。不为超过他们,主要自己用着舒服点。这篇文章主要是记录下我是如何从0到1是完成一款还算拿得出手的Markdown编辑器。

调研Markdown编辑器

国内、国外关于Markdown编辑器有很多。

  • editor.md

网址:https://pandao.github.io/editor.md/

是一款开源的、可嵌入的 Markdown 在线编辑器(组件),基于 CodeMirror、jQuery 和 Marked 构建。这个组件好像是国内开发的,个人之前用着还可以。

  • typora

网址:https://www.typora.io/

Typora是一款免费的轻量级Markdown编辑器,它没有Mou,Haroopad等Markdown编辑器那么大名鼎鼎,算是较为小众的一款产品。 凭良心说话,我用过的Markdown编辑器也有好几款,其中包括:小书匠,Haroopad,Atom等,但Typora是最合我心意的一款编辑器了,其轻量、快速、易于上手,使用起来简直不要太舒服!!

  • tui-editor

网址:https://ui.toast.com/tui-editor

这是一款Markdown组件,通过调研决定用它。为什么?确认过眼神~

技术栈

  • Vue.js
  • tui-editor

实战

确定好技术栈之后,我们就得脚踏实地地干活了。

1. 搭建Vue脚手架

我们会使用VueCLI搭建一个最基础的项目,这里暂时不需要Vue-routerVuex这些插件,所以尽可能轻装。

2. 创建编辑器组件

我们会在components文件目录下创建一个Editor.vue文件,这个文件也就是我们的主战场,大部分操作都会在这个文件。

3. 配置编辑器组件

在配置编辑器时,有以下几点使我非常困惑,以致于花费了大量时间。

  1. 代码没有被高亮
  2. 语言不是中文
  3. 编辑器样式有问题

以上这几个问题通过以下措施才得以解决:

  1. 通过阅读文档:https://nhn.github.io/tui.editor/latest/
  2. 访问Github网站:https://github.com/nhn/tui.editor

Editor.vue

<template><div class="main"><div id="editor"></div></div>
</template>
<script>
import Editor from "@toast-ui/editor";
import hljs from "highlight.js";
import codeSyntaxHighlight from "@toast-ui/editor-plugin-code-syntax-highlight";
import '@toast-ui/editor/dist/i18n/zh-cn.js';import "highlight.js/styles/github.css";
import "codemirror/lib/codemirror.css"; // Editor's Dependency Style
import "@toast-ui/editor/dist/toastui-editor.css"; // Editor's Style
import "@/styles/index.css";
export default {components: {},data() {return {editor: null};},mounted() {this.editor = new Editor({el: document.getElementById("editor"),plugins: [[codeSyntaxHighlight, {hljs}]],previewStyle: "vertical",height: "100vh",initialEditType: "markdown",minHeight: "200px",initialValue: "",placeholder: "你想写点什么...",language:'zh-CN',useCommandShortcut: true,useDefaultHTMLSanitizer: true,usageStatistics: false,hideModeSwitch: false,viewer: true,toolbarItems: ["heading","bold","italic","strike","divider","hr","quote","divider","ul","ol","task","indent","outdent","divider","table","image","link","divider","code","codeblock",],});this.editor.getUI().getToolbar().removeItem("21");},
};
</script>

看似上面几行代码,但是也是很费劲才得以完成。

增加功能

首先,我开发这个程序的初衷是更好地方便自己写文章,所以,我定下了这几个需求:

  1. 可复制HTML格式文本,方便复制到微信公众号
  2. 可复制Markdown文本,方便可以复制到稀土掘金、csdn这些博客网站上发布
  3. 可下载Markdown文件,更加方便保存和移动

因篇幅原因,先奉上主要逻辑代码。这里我使用了clipboard这个将文本复制到剪贴板的插件。网址:https://clipboardjs.com/
另外,downloadBlobAsFile方法主要是创建Blob对象,然后通过a标签的download属性进行下载。

downloadBlobAsFile.js

export default function downloadBlobAsFile(data, filename) {const contentType = 'application/octet-stream';if (!data) {console.error(' No data');return;}if (!filename) {filename = 'filetodonwload.txt';}if (typeof data === 'object') {data = JSON.stringify(data, undefined, 4);}let blob = new Blob([data], {type: contentType});let e = document.createEvent('MouseEvents');let a = document.createElement('a');a.download = filename;a.href = URL.createObjectURL(blob);a.dataset.downloadurl = [contentType, a.download, a.href].join(':');e.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);a.dispatchEvent(e);
}

Editor.vue

<template><div class="main"><div class="tools"><el-buttonsize="mini"type="primary"@click="drawer = true">工具</el-button><el-buttonsize="mini"type="primary"@click="aboutView = true">关于</el-button><el-dialog:title="'工具'":visible.sync="drawer":append-to-body="true"><div class="tool-innter"><el-button type="primary" @click="getHtml" class="htmlbtn">复制HTML</el-button><el-button type="primary" @click="getMd" class="mdbtn">复制MarkDown</el-button><el-button type="primary" @click="downloadMd" class="downloadbtn">下载MarkDown</el-button></div></el-dialog><el-dialog:title="'关于'":visible.sync="aboutView":append-to-body="true"><h3>Simple·MarkDown编辑器</h3><ul class="functionList"><li v-for="(item,index) in functionList" :key="index">{{item}}</li></ul><h3>作者</h3><ul class="functionList"><li v-for="(item,index) in authorList" :key="index">{{item}}</li></ul><div class="wxcode"><img src="../assets/wxcode.jpeg" alt=""></div></el-dialog></div><div id="editor"></div></div>
</template>
<script>
import Editor from "@toast-ui/editor";
import Clipboard from "clipboard";
import hljs from "highlight.js";
import codeSyntaxHighlight from "@toast-ui/editor-plugin-code-syntax-highlight";
import '@toast-ui/editor/dist/i18n/zh-cn.js';
import downloadBlobAsFile from "../utils/download";import "highlight.js/styles/github.css"; //https://github.com/highlightjs/highlight.js/tree/master/src/styles
import "codemirror/lib/codemirror.css"; // Editor's Dependency Style
import "@toast-ui/editor/dist/toastui-editor.css"; // Editor's Style
import "@/styles/index.css";
export default {components: {},data() {return {editor: null,drawer: false,aboutView: false,functionList:['页面简约','功能实用','支持稀土掘金、CSDN、微信公众号、知乎','可复制HTML、MarkDown','可下载MarkDown文件'],authorList:['作者:Vam的金豆之路','欢迎关注我的公众号:前端历劫之路','我创建了一个技术交流、文章分享群,群里有很多大厂的前端大佬,关注公众号后,点击下方菜单了解更多即可加我微信,期待你的加入']};},methods: {// 复制HTMLgetHtml() {const clipboard = new Clipboard(".htmlbtn", {target: () => this.editor.preview.el,});clipboard.on("success", () => {this.$message({message: "复制成功",type: "success",});clipboard.destroy();});clipboard.on("error", () => {this.$message.error("复制失败");clipboard.destroy();});},// 复制MarkdowngetMd() {const clipboard = new Clipboard(".mdbtn", {text: () => this.editor.getMarkdown(),});clipboard.on("success", () => {this.$message({message: "复制成功",type: "success",});clipboard.destroy();});clipboard.on("error", () => {this.$message.error("复制失败");clipboard.destroy();});},// 下载MarkdowndownloadMd() {if (this.editor.getMarkdown().trim()) {downloadBlobAsFile(this.editor.getMarkdown(), "unnamed.md");} else {this.$message.error("下载失败");}},},mounted() {this.editor = new Editor({el: document.getElementById("editor"),plugins: [[codeSyntaxHighlight, {hljs}]],previewStyle: "vertical",height: "100vh",initialEditType: "markdown",minHeight: "200px",initialValue: "",placeholder: "你想写点什么...",language:'zh-CN',useCommandShortcut: true,useDefaultHTMLSanitizer: true,usageStatistics: false,hideModeSwitch: false,viewer: true,toolbarItems: ["heading","bold","italic","strike","divider","hr","quote","divider","ul","ol","task","indent","outdent","divider","table","image","link","divider","code","codeblock",],});this.editor.getUI().getToolbar().removeItem("21");},
};
</script>

针对微信公众号进行样式优化

::v-deep是深度作用选择器,主要是为了覆盖原有的样式所用。

::v-deep ul li {list-style-type: disc !important;
}::v-deep ol li {list-style-type: decimal !important;
}::v-deep ul li::before, ::v-deep ol li::before {content: none;
}
::v-deep .tui-editor-contents p>code{background-color: #fff5f5;color: #ff502c;
}
::v-deep .tui-editor-contents pre {width: 100%;overflow: auto;
}

线上体验

https://www.maomin.club/site/mdeditor/

结语

谢谢阅读,希望没有浪费你的时间。

源码地址:

https://github.com/maomincoding/simpleMdEditor

如果对你有帮助,欢迎Star~

我创建了一个技术交流、文章分享群,群里有很多大厂的前端大佬,关注公众号后,点击下方菜单了解更多即可加我微信,期待你的加入。

公众号:前端历劫之路

我熬夜开发了一款简约实用、支持多平台的Markdown在线编辑器(开源)相关推荐

  1. markdown在线编辑器 editor.md 二次开发详细教程

    markdown在线编辑器 editor.md 二次开发 需求 经常需要在网络论坛发布文章进行宣传,但每个论坛的编写格式存在差异,给发布带来了很大的障碍. 最近markdown格式的兴起,给广大发布者 ...

  2. confluence 编辑器这次没有加载_介绍10款平时项目里使用比较多的在线编辑器,有需要可以收藏起来

    我这里只是收集一些常用在线编辑器,对编辑器的功能,性能,使用难易程度不做任何评测,因为每个人的使用习惯不一样,使用场景也不一样. UEditor (百度开发) UEditor 是一套开源的在线HTML ...

  3. python在线编辑器最新_Editor.md 二次开发-markdown在线编辑器

    需求分析 经常需要在网络论坛发布文章进行宣传良心工作室最新免费服务,但每个论坛的编写格式存在差异,给发布带来了很大的障碍. 最近markdown格式的兴起,给广大发布者带来了福音,一种文档格式大部分网 ...

  4. 超好用!5款完全免费、支持全平台的笔记软件

    5款小众好用的笔记软件,完全免费.跨平台 好记忆不如一个烂笔头,对于这句话,我深以为然. 我觉得养成做笔记的习惯,对于工作和学习都能够提供很大的帮助. 不同的人有不同整理笔记的习惯,有的同学会使用各种 ...

  5. 自己开发的MarkDown在线编辑器越来越完善了,心里感到高兴。

    先晒一下它的样子.当然,我一开始就企图做到这四点:随时随地可以自动保存草稿内容到服务器:键盘快捷键进行Markdown格式编辑:可以分段编辑(万一文章比较长呢):还有就是手机上也能用大部分功能.现在这 ...

  6. CicadasCMS(知了CMS)是一款基于springboot、mybatis、beetl等框架开发的一款内容管理系统

    介绍: CicadasCMS CicadasCMS是用springboot+mybatis+beetl开发的一款CMS,支持自定义内容模型.模板标签.全站静态化等功能. 网盘下载地址: http:// ...

  7. 开发了一款年龄计算器,现无偿开源给大家

    闲来无事,开发了一款智能的年龄计算器. 鉴于程序员的开源精神,现无偿开源给大家使用. 源代码如下: 只要在下方输入你的年龄,就可以计算出你今年的实际年龄. 真棒!代码改变世界!

  8. 重磅 | 推荐一款技术人必备的写作神器 (支持多平台自动同步)

    很多技术人都特别喜欢写技术文章并发布到自己的博客上,写技术文章有两个好处:一个是进行一次技术知识的总结和提高,另一个就是通过技术文章的传播,可以打造自己的影响力. 当下,随着自媒体的高速发展,越来越多 ...

  9. 重磅 | 推荐一款技术人必备的写作神器 (支持多平台博客群发)

    很多技术人都特别喜欢写技术文章并发布到自己的博客上,写技术文章有两个好处:一个是进行一次技术知识的总结和提高,另一个就是通过技术文章的传播,可以打造自己的影响力. 当下,随着自媒体的高速发展,越来越多 ...

  10. 5款让Web前端开发人员更轻松的实用工具

    Web前端的工作在以前称之为网页美工,但随着flash逐渐退出网页设计的舞台之后,HTML+css+JavaScript为核心的前端技术成功的完成了技术栈的升级,是的Web前端工程师的名头也越叫越响. ...

最新文章

  1. [C] [字节跳动] [编程题] 手串
  2. 使用Python,EoN模拟网络中的疾病扩散模型,并结合matplotlib绘图
  3. C# 中DateTime的各种使用
  4. 移动apn接入点哪个快_移动4g网速最快接入点_2020移动最佳APN接入点
  5. python脚本实例手机端-用Python实现自动化操作Android手机
  6. TrueSec引导的Linux系统和安全检测工具预览
  7. 深入理解null的原理
  8. ubuntu 12.04 /sbin/ldconfig.real: /usr/local/lib/*.so.8 不是符号连接 解决办法
  9. 我了解到的面试的一些小内幕!顺利通过阿里Android岗面试
  10. mnist torch加载fashion_Pytorch加载并可视化FashionMNIST指定层(Udacity)
  11. mysql5.6触发器,MYSQL5.6创建存储过程和触发器
  12. 通用时区:你应该知道的数据库时区知识
  13. powershell excel 导入 sqlserver
  14. 报表问题~~只有这么多分了~~~~-_-~
  15. 电脑网络安全_网络安全月 | 戳视频!帮你的电脑远离“黑客”
  16. random-生成随机数模块
  17. 灰色模型GM与时间无关
  18. 【中等】迷你语法分析器
  19. C++FTP客户端库:ftplibpp的使用
  20. restore和recover区别

热门文章

  1. python elif invalid syntax_Python错误集锦:if和elif语句提示:SyntaxError: invalid syntax
  2. C++控制台五子棋(带背景音乐)
  3. 中国不必模仿印度软件模式
  4. RK平台RAM和ROM容量计算
  5. 用Asp.net 就能轻松实现铁道部的订票系统
  6. 辞职信前端源码文件分享
  7. el-empty Empty 空状态 自定义图片 使用本地图片
  8. 半闲居士视觉SLAM十四讲笔记(5)相机与图像 - part 2 图像及 OpenCV 操作、点云拼接
  9. 小米5之Root攻略
  10. 2、slf4j绑定JUL(桥接模式)