自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

我熬夜開(kāi)發(fā)了一款簡(jiǎn)約實(shí)用、支持多平臺(tái)的Markdown在線編輯器(開(kāi)源)

開(kāi)發(fā) 開(kāi)發(fā)工具
之前,一直想開(kāi)發(fā)一款屬于自己的Markdown編輯器,主要是自己平常寫(xiě)文章可以更加靈活操作,另外擴(kuò)寬自己的視野也是非常不錯(cuò)的選擇啊!所以在周末就決定玩耍一番。首先我調(diào)研了很多線上熱門(mén)的md編輯器,都很優(yōu)秀。不為超過(guò)他們,主要自己用著舒服點(diǎn)。這篇文章主要是記錄下我是如何從0到1是完成一款還算拿得出手的Markdown編輯器。

[[385871]]

 前言

之前,一直想開(kāi)發(fā)一款屬于自己的Markdown編輯器,主要是自己平常寫(xiě)文章可以更加靈活操作,另外擴(kuò)寬自己的視野也是非常不錯(cuò)的選擇啊!所以在周末就決定玩耍一番。首先我調(diào)研了很多線上熱門(mén)的md編輯器,都很優(yōu)秀。不為超過(guò)他們,主要自己用著舒服點(diǎn)。這篇文章主要是記錄下我是如何從0到1是完成一款還算拿得出手的Markdown編輯器。

完成項(xiàng)目一覽



調(diào)研Markdown編輯器

國(guó)內(nèi)、國(guó)外關(guān)于Markdown編輯器有很多。

editor.md

網(wǎng)址:https://pandao.github.io/editor.md/

是一款開(kāi)源的、可嵌入的 Markdown 在線編輯器(組件),基于 CodeMirror、jQuery 和 Marked 構(gòu)建。這個(gè)組件好像是國(guó)內(nèi)開(kāi)發(fā)的,個(gè)人之前用著還可以。

typora

網(wǎng)址:https://www.typora.io/

Typora是一款免費(fèi)的輕量級(jí)Markdown編輯器,它沒(méi)有Mou,Haroopad等Markdown編輯器那么大名鼎鼎,算是較為小眾的一款產(chǎn)品。憑良心說(shuō)話,我用過(guò)的Markdown編輯器也有好幾款,其中包括:小書(shū)匠,Haroopad,Atom等,但Typora是最合我心意的一款編輯器了,其輕量、快速、易于上手,使用起來(lái)簡(jiǎn)直不要太舒服!!

tui-editor

網(wǎng)址:https://ui.toast.com/tui-editor

這是一款Markdown組件,通過(guò)調(diào)研決定用它。為什么?確認(rèn)過(guò)眼神~

技術(shù)棧

  • Vue.js
  • tui-editor

實(shí)戰(zhàn)

確定好技術(shù)棧之后,我們就得腳踏實(shí)地地干活了。

1. 搭建Vue腳手架

我們會(huì)使用VueCLI搭建一個(gè)最基礎(chǔ)的項(xiàng)目,這里暫時(shí)不需要Vue-router、Vuex這些插件,所以盡可能輕裝。

2. 創(chuàng)建編輯器組件

我們會(huì)在components文件目錄下創(chuàng)建一個(gè)Editor.vue文件,這個(gè)文件也就是我們的主戰(zhàn)場(chǎng),大部分操作都會(huì)在這個(gè)文件。

3. 配置編輯器組件

在配置編輯器時(shí),有以下幾點(diǎn)使我非常困惑,以致于花費(fèi)了大量時(shí)間。

  1. 代碼沒(méi)有被高亮
  2. 語(yǔ)言不是中文
  3. 編輯器樣式有問(wèn)題

以上這幾個(gè)問(wèn)題通過(guò)以下措施才得以解決:

  1. 通過(guò)閱讀文檔:https://nhn.github.io/tui.editor/latest/
  2. 訪問(wèn)Github網(wǎng)站:https://github.com/nhn/tui.editor

Editor.vue

  1. <template> 
  2.   <div class="main"
  3.     <div id="editor"></div> 
  4.   </div> 
  5. </template> 
  6. <script> 
  7. import Editor from "@toast-ui/editor"
  8. import hljs from "highlight.js"
  9. import codeSyntaxHighlight from "@toast-ui/editor-plugin-code-syntax-highlight"
  10. import '@toast-ui/editor/dist/i18n/zh-cn.js'
  11.  
  12. import "highlight.js/styles/github.css"
  13. import "codemirror/lib/codemirror.css"; // Editor's Dependency Style 
  14. import "@toast-ui/editor/dist/toastui-editor.css"; // Editor's Style 
  15. import "@/styles/index.css"
  16. export default { 
  17.   components: {}, 
  18.   data() { 
  19.     return { 
  20.       editor: null 
  21.     }; 
  22.   }, 
  23.   mounted() { 
  24.     this.editor = new Editor({ 
  25.       el: document.getElementById("editor"), 
  26.       plugins: [[codeSyntaxHighlight, {hljs}]], 
  27.       previewStyle: "vertical"
  28.       height: "100vh"
  29.       initialEditType: "markdown"
  30.       minHeight: "200px"
  31.       initialValue: ""
  32.       placeholder: "你想寫(xiě)點(diǎn)什么..."
  33.       language:'zh-CN'
  34.       useCommandShortcut: true
  35.       useDefaultHTMLSanitizer: true
  36.       usageStatistics: false
  37.       hideModeSwitch: false
  38.       viewer: true
  39.       toolbarItems: [ 
  40.         "heading"
  41.         "bold"
  42.         "italic"
  43.         "strike"
  44.         "divider"
  45.         "hr"
  46.         "quote"
  47.         "divider"
  48.         "ul"
  49.         "ol"
  50.         "task"
  51.         "indent"
  52.         "outdent"
  53.         "divider"
  54.         "table"
  55.         "image"
  56.         "link"
  57.         "divider"
  58.         "code"
  59.         "codeblock"
  60.       ], 
  61.     }); 
  62.     this.editor.getUI().getToolbar().removeItem("21"); 
  63.   }, 
  64. }; 
  65. </script> 

看似上面幾行代碼,但是也是很費(fèi)勁才得以完成。

增加功能

首先,我開(kāi)發(fā)這個(gè)程序的初衷是更好地方便自己寫(xiě)文章,所以,我定下了這幾個(gè)需求:

  1. 可復(fù)制HTML格式文本,方便復(fù)制到微信公眾號(hào)
  2. 可復(fù)制Markdown文本,方便可以復(fù)制到稀土掘金、csdn這些博客網(wǎng)站上發(fā)布
  3. 可下載Markdown文件,更加方便保存和移動(dòng)

因篇幅原因,先奉上主要邏輯代碼。這里我使用了clipboard這個(gè)將文本復(fù)制到剪貼板的插件。網(wǎng)址:https://clipboardjs.com/。

另外,downloadBlobAsFile方法主要是創(chuàng)建Blob對(duì)象,然后通過(guò)a標(biāo)簽的download屬性進(jìn)行下載。

downloadBlobAsFile.js

  1. export default function downloadBlobAsFile(data, filename) { 
  2.     const contentType = 'application/octet-stream'
  3.     if (!data) { 
  4.         console.error(' No data'); 
  5.         return
  6.     } 
  7.  
  8.     if (!filename) { 
  9.         filename = 'filetodonwload.txt'
  10.     } 
  11.  
  12.     if (typeof data === 'object') { 
  13.         data = JSON.stringify(data, undefined, 4); 
  14.     } 
  15.  
  16.     let blob = new Blob([data], {type: contentType}); 
  17.     let e = document.createEvent('MouseEvents'); 
  18.     let a = document.createElement('a'); 
  19.  
  20.     a.download = filename; 
  21.     a.href = URL.createObjectURL(blob); 
  22.     a.dataset.downloadurl = [contentType, a.download, a.href].join(':'); 
  23.     e.initMouseEvent('click'truefalse, window, 0, 0, 0, 0, 0, falsefalsefalsefalse, 0, null); 
  24.     a.dispatchEvent(e); 

Editor.vue

  1. <template> 
  2.   <div class="main"
  3.     <div class="tools"
  4.       <el-button 
  5.           size="mini" 
  6.           type="primary" 
  7.           @click="drawer = true" 
  8.       >工具</el-button> 
  9.       <el-button 
  10.           size="mini" 
  11.           type="primary" 
  12.           @click="aboutView = true" 
  13.       >關(guān)于</el-button> 
  14.       <el-dialog 
  15.           :title="'工具'" 
  16.           :visible.sync="drawer" 
  17.           :append-to-body="true" 
  18.       > 
  19.         <div class="tool-innter"
  20.           <el-button type="primary" @click="getHtml" class="htmlbtn" 
  21.           >復(fù)制HTML 
  22.           </el-button 
  23.           > 
  24.           <el-button type="primary" @click="getMd" class="mdbtn" 
  25.           >復(fù)制MarkDown 
  26.           </el-button 
  27.           > 
  28.           <el-button type="primary" @click="downloadMd" class="downloadbtn" 
  29.           >下載MarkDown 
  30.           </el-button 
  31.           > 
  32.         </div> 
  33.       </el-dialog> 
  34.       <el-dialog 
  35.           :title="'關(guān)于'" 
  36.           :visible.sync="aboutView" 
  37.           :append-to-body="true" 
  38.       > 
  39.         <h3>Simple·MarkDown編輯器</h3> 
  40.         <ul class="functionList"
  41.           <li v-for="(item,index) in functionList" :key="index"
  42.             {{item}} 
  43.           </li> 
  44.         </ul> 
  45.         <h3>作者</h3> 
  46.         <ul class="functionList"
  47.           <li v-for="(item,index) in authorList" :key="index">{{item}}</li> 
  48.         </ul> 
  49.         <div class="wxcode"
  50.           <img src="../assets/wxcode.jpeg" alt=""
  51.         </div> 
  52.       </el-dialog> 
  53.     </div> 
  54.     <div id="editor"></div> 
  55.   </div> 
  56. </template> 
  57. <script> 
  58. import Editor from "@toast-ui/editor"
  59. import Clipboard from "clipboard"
  60. import hljs from "highlight.js"
  61. import codeSyntaxHighlight from "@toast-ui/editor-plugin-code-syntax-highlight"
  62. import '@toast-ui/editor/dist/i18n/zh-cn.js'
  63. import downloadBlobAsFile from "../utils/download"
  64.  
  65. import "highlight.js/styles/github.css"; //https://github.com/highlightjs/highlight.js/tree/master/src/styles 
  66. import "codemirror/lib/codemirror.css"; // Editor's Dependency Style 
  67. import "@toast-ui/editor/dist/toastui-editor.css"; // Editor's Style 
  68. import "@/styles/index.css"
  69. export default { 
  70.   components: {}, 
  71.   data() { 
  72.     return { 
  73.       editor: null
  74.       drawer: false
  75.       aboutView: false
  76.       functionList:['頁(yè)面簡(jiǎn)約','功能實(shí)用','支持稀土掘金、CSDN、微信公眾號(hào)、知乎','可復(fù)制HTML、MarkDown','可下載MarkDown文件'], 
  77.       authorList:['作者:Vam的金豆之路','歡迎關(guān)注我的公眾號(hào):前端歷劫之路','我創(chuàng)建了一個(gè)技術(shù)交流、文章分享群,群里有很多大廠的前端大佬,關(guān)注公眾號(hào)后,點(diǎn)擊下方菜單了解更多即可加我微信,期待你的加入'
  78.     }; 
  79.   }, 
  80.   methods: { 
  81.     // 復(fù)制HTML 
  82.     getHtml() { 
  83.       const clipboard = new Clipboard(".htmlbtn", { 
  84.         target: () => this.editor.preview.el, 
  85.       }); 
  86.       clipboard.on("success", () => { 
  87.         this.$message({ 
  88.           message: "復(fù)制成功"
  89.           type: "success"
  90.         }); 
  91.         clipboard.destroy(); 
  92.       }); 
  93.       clipboard.on("error", () => { 
  94.         this.$message.error("復(fù)制失敗"); 
  95.         clipboard.destroy(); 
  96.       }); 
  97.     }, 
  98.     // 復(fù)制Markdown 
  99.     getMd() { 
  100.       const clipboard = new Clipboard(".mdbtn", { 
  101.         text: () => this.editor.getMarkdown(), 
  102.       }); 
  103.       clipboard.on("success", () => { 
  104.         this.$message({ 
  105.           message: "復(fù)制成功"
  106.           type: "success"
  107.         }); 
  108.         clipboard.destroy(); 
  109.       }); 
  110.       clipboard.on("error", () => { 
  111.         this.$message.error("復(fù)制失敗"); 
  112.         clipboard.destroy(); 
  113.       }); 
  114.     }, 
  115.     // 下載Markdown 
  116.     downloadMd() { 
  117.       if (this.editor.getMarkdown().trim()) { 
  118.         downloadBlobAsFile(this.editor.getMarkdown(), "unnamed.md"); 
  119.       } else { 
  120.         this.$message.error("下載失敗"); 
  121.       } 
  122.     }, 
  123.   }, 
  124.   mounted() { 
  125.     this.editor = new Editor({ 
  126.       el: document.getElementById("editor"), 
  127.       plugins: [[codeSyntaxHighlight, {hljs}]], 
  128.       previewStyle: "vertical"
  129.       height: "100vh"
  130.       initialEditType: "markdown"
  131.       minHeight: "200px"
  132.       initialValue: ""
  133.       placeholder: "你想寫(xiě)點(diǎn)什么..."
  134.       language:'zh-CN'
  135.       useCommandShortcut: true
  136.       useDefaultHTMLSanitizer: true
  137.       usageStatistics: false
  138.       hideModeSwitch: false
  139.       viewer: true
  140.       toolbarItems: [ 
  141.         "heading"
  142.         "bold"
  143.         "italic"
  144.         "strike"
  145.         "divider"
  146.         "hr"
  147.         "quote"
  148.         "divider"
  149.         "ul"
  150.         "ol"
  151.         "task"
  152.         "indent"
  153.         "outdent"
  154.         "divider"
  155.         "table"
  156.         "image"
  157.         "link"
  158.         "divider"
  159.         "code"
  160.         "codeblock"
  161.       ], 
  162.     }); 
  163.     this.editor.getUI().getToolbar().removeItem("21"); 
  164.   }, 
  165. }; 
  166. </script> 

針對(duì)微信公眾號(hào)進(jìn)行樣式優(yōu)化

::v-deep是深度作用選擇器,主要是為了覆蓋原有的樣式所用。

  1. ::v-deep ul li { 
  2.   list-style-type: disc !important; 
  3.  
  4. ::v-deep ol li { 
  5.   list-style-type: decimal !important; 
  6.  
  7. ::v-deep ul li::before, ::v-deep ol li::before { 
  8.   content: none; 
  9. ::v-deep .tui-editor-contents p>code{ 
  10.   background-color: #fff5f5; 
  11.   color: #ff502c; 
  12. ::v-deep .tui-editor-contents pre { 
  13.   width: 100%; 
  14.   overflow: auto; 

線上體驗(yàn)

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

結(jié)語(yǔ)

謝謝閱讀,希望沒(méi)有浪費(fèi)你的時(shí)間。

源碼地址:

https://github.com/maomincoding/simpleMdEditor

 

責(zé)任編輯:姜華 來(lái)源: 前端歷劫之路
相關(guān)推薦

2023-06-20 00:04:18

框架開(kāi)發(fā)UMD

2020-09-18 06:00:51

開(kāi)源Markdown編輯器

2021-11-24 09:12:11

Markdown編輯器Linux

2020-09-16 10:27:50

MarkDown編輯器編程

2024-03-06 08:26:29

2017-05-23 19:19:16

開(kāi)源Markdown編輯器

2022-08-31 08:32:22

數(shù)據(jù)可視化項(xiàng)目nocode

2021-08-26 05:15:22

圖片編輯器 H5-DooringMitu-Doorin

2021-10-27 14:55:57

Mark TextMarkdown編輯器

2021-10-21 10:58:03

Markdown編輯器

2022-04-27 08:42:20

Markdown編輯神器

2021-04-08 14:58:59

開(kāi)發(fā)前端編輯器

2023-09-10 23:22:33

Zettlr筆記編輯器

2022-01-10 18:16:24

編輯器Typora Markdown

2021-06-23 06:12:38

Subtitld編輯器開(kāi)源

2022-09-05 13:16:42

MicroVim編輯器

2021-12-23 10:59:30

開(kāi)源技術(shù) 軟件

2021-04-12 08:31:53

PC-Dooring項(xiàng)目PC端搭建

2014-09-05 09:45:46

2021-04-04 08:16:09

NewsFlash閱讀器開(kāi)源
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)