一、基础配置
当前前端渲染markdown文件比较好的插件就是marked.js了。
import marked from 'marked'
const rendererMD = new marked.Renderer()
marked.setOptions({
renderer: rendererMD,
gfm: true,
tables: true,
breaks: false,
pedantic: false,
sanitize: false,
smartLists: true,
smartypants: false,
})
// 对应后端接口路径,或者本地路径
axios.get('/md' + this.$route.query.pageUrl).then(res => {
this.markedHtml = marked(res.data) // 解析好的markdown,直接在对应容器标签上传进v-html里面即可
})
二、设置回调
如果需要实现点击放大的功能,那就需要在所有img标签上绑定回调函数,获取到当前dom或者是src
刚好,markedjs给我们提供了img标签的回调
// marked解析过程中解析到图片的回调,为每个img标签绑定点击事件,并传递当前事件以及href图片链接
rendererMD.image = function(href, title, text) {
return `<img οnclick="showMarkedImage(event, '${href}')" src="${href}" alt="${text}" title="${
title ? title : ''
}">`
}
监听事件
我这里实现了投机取巧的方式,直接全屏显示了。
window.showMarkedImage = function(e, href) {
let el = e.target
let rfs =
el.requestFullScreen ||
el.webkitRequestFullScreen ||
el.mozRequestFullScreen ||
el.msRequestFullScreen
if (rfs) {
rfs.call(el)
}
console.log(href)
}
三、最终代码
import marked from 'marked'
import axios from 'axios'
import highlight from 'highlight.js'
import 'highlight.js/styles/github.css' //css可以找自己喜欢的样式
export default {
name: 'index',
data() {
return {
markedHtml: ''
}
},
mounted() {
window.showMarkedImage = function(e, href) {
let el = e.target
let rfs =
el.requestFullScreen ||
el.webkitRequestFullScreen ||
el.mozRequestFullScreen ||
el.msRequestFullScreen
if (rfs) {
rfs.call(el)
}
console.log(href)
}
this.mdConvert()
},
methods: {
mdConvert() {
const rendererMD = new marked.Renderer()
rendererMD.image = function(href, title, text) {
return `<img οnclick="showMarkedImage(event, '${href}')" src="${href}" alt="${text}" title="${
title ? title : ''
}">`
}
marked.setOptions({
renderer: rendererMD,
gfm: true,
tables: true,
breaks: false,
pedantic: false,
sanitize: false,
smartLists: true,
smartypants: false,
highlight: function(code) {
return highlight.highlightAuto(code).value
}
})
axios.get('/md' + this.$route.query.pageUrl).then(res => {
this.markedHtml = marked(res.data).replace(
/<pre>/g,
"<pre class='hljs'>"
)
})
}
}
}
四、优化方向
我们已经能够获取当前被点击图片的href链接,这样我们其实可以按照自己的想法或者是需求做很多事情,比如自己手动实现一个放大显示框、利用v-viewer实现放大效果等等
而且marked.js还提供了其他很多的回调,我们可以按需使用
五、注意事项
rendererMD.image
只对按照md语法插入的图片有效,例如:
![](https://img1.baidu.com/it/u=1960110688,1786190632&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=281)
对使用html语法插入的图片不生效,例如:
<img src="https://img1.baidu.com/it/u=1960110688,1786190632&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=281" style="zoom: 33%;" />
如果我们希望对html语法插入的图片也生效,则需要对html标签进行处理即可。直接将点击事件加到img标签上就行了。
将原img标签稍加处理:
<img src="https://img1.baidu.com/it/u=1960110688,1786190632&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=281" onclick="showMarkedImage(event, 'https://img1.baidu.com/it/u=1960110688,1786190632&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=281')" style="zoom: 33%;" />
如果你不想每次对原md文件进行修改,也可以和
rendererMD.image
回调一样统一在
rendererMD.html
回调中实现:
这里仅作为思路参考,具体实现大家自己发挥
rendererMD.html = function(html) {
console.log('11', html)
if (html.startsWith('<img')) {
// 实现图片点击放大
const objE = document.createElement('div')
objE.innerHTML = html
const imgEl = objE.childNodes[0]
return `<img οnclick="showMarkedImage(event, '${imgEl.src}')" src="${imgEl.src}" alt="${imgEl.alt}" title="${
imgEl.title ? imgEl.title : '点击全屏显示'
}" style="${imgEl.style.cssText}"/>`
}
return html
}