效果圖
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()
})
最後,踩坑不易,點個贊吧 ^ _ ^