mavon-editor markdown 編輯器配置及代碼塊高亮顯示並添加行號

效果圖

代碼塊效果圖copy

mavon-editor markdown 編輯器

項目使用mavon-editor markdown編輯器,由於項目需要存儲在數據庫中的是md文件,所以需要通過marked轉譯爲HTML文件

引入mavon-editor

//安裝
npm i mavon-editor
//引入
import mavonEditor from 'mavon-editor'
import 'mavon-editor/dist/css/index.css'
Vue.use(mavonEditor)
//使用
<template>
	<mavon-editor
	      v-model="content"
	      :placeholder="'Edit ···'"
	      ref="md"
	      @imgAdd="$imgAdd"
	      @imgDel="$imgDel"
	      @change="change"
	      :toolbars="toolbars"
	      :toolbarsBackground="'#f9f9f9'"
	      style="height: calc(100vh - 50px)"
	    />
</template>
//參數
toolbars: {
        bold: true, // 粗體
        italic: true, // 斜體
        header: true, // 標題
        underline: true, // 下劃線
        strikethrough: true, // 中劃線
        mark: true, // 標記
        superscript: true, // 上角標
        subscript: true, // 下角標
        quote: true, // 引用
        ol: true, // 有序列表
        ul: true, // 無序列表
        link: true, // 鏈接
        imagelink: true, // 圖片鏈接
        code: true, // code
        table: true, // 表格
        fullscreen: false, // 全屏編輯
        readmodel: false, // 沉浸式閱讀
        htmlcode: true, // 展示html源碼
        help: true, // 幫助
        /* 1.3.5 */
        undo: true, // 上一步
        redo: true, // 下一步
        trash: true, // 清空
        save: false, // 保存(觸發events中的save事件)
        /* 1.4.2 */
        navigation: true, // 導航目錄
        /* 2.1.8 */
        alignleft: true, // 左對齊
        aligncenter: true, // 居中
        alignright: true, // 右對齊
        /* 2.2.1 */
        subfield: true, // 單雙欄模式
        preview: false // 預覽
      }
//methods
methods: {
    $imgAdd (pos, $file) {
      // 第一步.將圖片上傳到服務器.
      var formdata = new FormData()
      formdata.append('image', $file)
      this.img_file[pos] = $file
      this.$http({
        url: '/api/edit/uploadimg',
        method: 'post',
        data: formdata,
        headers: { 'Content-Type': 'multipart/form-data' }
      }).then((res) => {
        let _res = res.data
        // 第二步.將返回的url替換到文本原位置![...](0) -> ![...](url)
        this.$refs.md.$img2Url(pos, _res.url)
      })
    },
    $imgDel (pos) {
      delete this.img_file[pos]
    },
    change (value, render) {
      this.html = render
    },
    // 提交
    submit () {
      console.log(this.content)
      console.log(this.html)
    }
  }

注:該編輯器支持代碼塊高亮,可通過codeStyle自定義配置,本項目爲了靈活運用,使用的是自定義的代碼樣式
具體參數請參考mavon-editor官方文檔

導入文件
數據庫存儲數據爲md文件,所以需要轉譯爲html文件

安裝

npm install marked

轉譯

import marked from 'marked'             //引入
//通過marked()轉譯
this.article.html = marked(this.article.content)

代碼塊高亮顯示

引入

npm install highlight.js

配置
新建hljs.js,註冊全局指令

import Vue from 'vue'
import hljs from 'highlight.js'
import 'highlight.js/styles/googlecode.css' // 樣式文件
Vue.directive('highlight', function (el) {
  let blocks = el.querySelectorAll('pre code')
  blocks.forEach((block) => {
    hljs.highlightBlock(block)
  })
})

main.js引入hljs.js

import './plugins/hljs'

組件中使用

<div class="markdown-body" v-html="article.content" v-highlight></div>

mavon-editor 編輯器需要單獨導入css文件

import 'mavon-editor/dist/markdown/github-markdown.min.css'

問題(按需使用):這樣使用會在頁面渲染的時候會出現高亮效果,但是這導致的問題是,切換路由的時候代碼高亮會消失。之所以產生這種現象,這跟 hljs.initHighlightingOnLoad()的定義有關,因爲只執行一次。
可以重寫 hljs.initHighlighting()方法,在組件的中是使用 hljs.highlightCode(),每次頁面加載的時候都會執行渲染代碼的邏輯

//在main.js中  
import 'highlight.js/styles/googlecode.css'
import hljs from 'highlight.js'
hljs.highlightCode = function () { 
	//自定義highlightCode方法,將只執行一次的邏輯去掉
	let blocks = document.querySelectorAll('pre code');
	[].forEach.call(blocks, hljs.highlightBlock);
};
//在組件中
export default {
  mounted(){
     hljs.highlightCode()
  }    
}

代碼塊添加行號
新建mavon.js


import $ from 'jquery'
import Vue from 'vue'
export const addCodeBtn = _ => {
	//markdown代碼存放在pre code 標籤對中
  $('pre code').each(function () {
    let lines = $(this).text().split('\n').length - 1
    //添加有序列表
    let $numbering = $('<ol/>').addClass('pre-numbering')
    //添加複製按鈕,此處使用的是element-ui icon 圖標
    let $copy = $('<i title="copy"/>').addClass('el-icon-document-copy code-copy')
    $(this)
      .parent()
      .addClass('code')
      .append($numbering)
      .append($copy)
    for (let i = 0; i <= lines; i++) {
      $numbering.append($('<li/>'))
    }
  })
  //監聽複製按鈕點擊事件
  $('pre.code i.code-copy').click(e => {
    let text = $(e.target).siblings('code').text()
    let element = $('<textarea>' + text + '</textarea>')
    $('body').append(element)
    element[0].select()
    document.execCommand('Copy')
    element.remove()
    //這裏是自定義的消息通知組件
    Vue.prototype.$notice.success({
      msg: '代碼複製成功'
    })
  })
}

在css文件中設置樣式

pre.code {
    position: relative;
    border-radius: 3px;
    border: 1px solid #C3CCD0;
    overflow: hidden;
    padding-left: 60px!important;
    code {
        line-height: 30px!important;
    }
    ol.pre-numbering {
        position: absolute;
        top: 0;
        left: 5px;
        line-height: 30px;
        padding: 16px 0;
        list-style-type:none;
        counter-reset:sectioncounter;
        margin-bottom: 0;
        li{
            margin-top: 0!important;
            &:before{
                content:counter(sectioncounter) "";
                counter-increment:sectioncounter;
                display: inline-block;
                width: 40px;
                text-align: center;
                border-right: solid 1px rgba(0, 0, 0, 0.53);
            }
        }
    }
    i.code-copy{
        position: absolute;
        top:0;
        right: 0;
        background-color: #464d5e;
        padding: 3px;
        margin: 3px 3px 0 0;
        font-size: 11px;
        border-radius: inherit;
        color: #f1f1f1;
        cursor: pointer;
        display: none;
    }
    &:hover i.code-copy{
        display: block;
    }
}

last
在組件中引入

import { addCodeBtn } from '../assets/js/mavon'
this.$nextTick(_ => {
  addCodeBtn()
})

ok最後,踩坑不易,點個贊吧 ^ _ ^

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章