在 Vue JS 中渲染 Markdown
Render Markdown In Vue JS
我用 Vue JS 做了一个小博客,它呈现带有标题和描述的帖子。我希望能够在描述中使用降价,所以我使用了 npm install marked
当我在数据中对文本进行硬编码时它工作正常,但试图传递我的描述本身来自道具时,它不起作用。
请参阅下面我的代码,我评论了哪些不起作用,并举了一个硬编码数据的例子。
知道如何解决这个问题吗?谢谢!
<template>
<div class="til-list">
<div v-for="til in tils" :key="til">
<div class="til">
<h3>{{ til.title }}</h3>
<p>{{ til.description }}</p>
<div v-html="markdownToHtml"></div>
<!-- <div v-html="markdownToHtml(til.description)"></div> -->
<span v-for="tag in til.tags" :key="tag"> #{{ tag }} </span>
</div>
</div>
</div>
</template>
<script>
import marked from "marked";
export default {
props: ["tils"],
// computed: {
// markdownToHtml(description) {
// return marked(this.description);
// },
// },
data() {
return {
markdown: "# Hello World",
};
},
computed: {
markdownToHtml() {
return marked(this.markdown);
},
},
};
</script>
尝试使用 methods
代替 computed
属性:
new Vue({
el: '#demo',
//props: ["tils"],
data() {
return {
tils: [{title: 'title 1', description: '<b>text</b>'}, {title: 'title 2', description: '<i>text</i>'}]
};
},
methods: {
markdownToHtml(description) {
return marked(description);
},
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
<div id="demo">
<div class="til-list">
<div v-for="(til, index) in tils" :key="index">
<div class="til">
<h3>{{ til.title }}</h3>
<p>{{ til.description }}</p>
<div v-html="markdownToHtml(til.description)"></div>
<!--<span v-for="tag in til.tags" :key="tag"> #{{ tag }} </span>-->
</div>
</div>
</div>
</div>
可以在纯 javascript 中尝试以下简单的解析器。
文档和详细信息可以在 https://github.com/casualwriter/powerpage-md-document
找到
//=== simple markdown parser
function simpleMarkdown(mdText) {
// first, handle syntax for code-block
mdText = mdText.replace(/\r\n/g, '\n')
mdText = mdText.replace(/\n~~~ *(.*?)\n([\s\S]*?)\n~~~/g, '<pre><code title=""></code></pre>' )
mdText = mdText.replace(/\n``` *(.*?)\n([\s\S]*?)\n```/g, '<pre><code title=""></code></pre>' )
// split by "pre>", skip for code-block and process normal text
var mdHTML = ''
var mdCode = mdText.split( 'pre>')
for (var i=0; i<mdCode.length; i++) {
if ( mdCode[i].substr(-2) == '</' ) {
mdHTML += '<pre>' + mdCode[i] + 'pre>'
} else {
mdHTML += mdCode[i].replace(/(.*)<$/, '')
.replace(/^##### (.*?)\s*#*$/gm, '<h5></h5>')
.replace(/^#### (.*?)\s*#*$/gm, '<h4 id=""></h4>')
.replace(/^### (.*?)\s*#*$/gm, '<h3 id=""></h3>')
.replace(/^## (.*?)\s*#*$/gm, '<h2 id=""></h2>')
.replace(/^# (.*?)\s*#*$/gm, '<h1 id=""></h1>')
.replace(/^-{3,}|^\_{3,}|^\*{3,}/gm, '<hr/>')
.replace(/``(.*?)``/gm, '<code></code>' )
.replace(/`(.*?)`/gm, '<code></code>' )
.replace(/^\>> (.*$)/gm, '<blockquote><blockquote></blockquote></blockquote>')
.replace(/^\> (.*$)/gm, '<blockquote></blockquote>')
.replace(/<\/blockquote\>\n<blockquote\>/g, '\n<br>' )
.replace(/<\/blockquote\>\n<br\><blockquote\>/g, '\n<br>' )
.replace(/!\[(.*?)\]\((.*?) "(.*?)"\)/gm, '<img alt="" src="" />')
.replace(/!\[(.*?)\]\((.*?)\)/gm, '<img alt="" src="" />')
.replace(/\[(.*?)\]\((.*?) "(.*?)"\)/gm, '<a href="" title=""></a>')
.replace(/<http(.*?)\>/gm, '<a href="http">http</a>')
.replace(/\[(.*?)\]\(\)/gm, '<a href=""></a>')
.replace(/\[(.*?)\]\((.*?)\)/gm, '<a href=""></a>')
.replace(/^[\*|+|-][ |.](.*)/gm, '<ul><li></li></ul>' ).replace(/<\/ul\>\n<ul\>/g, '\n' )
.replace(/^\d[ |.](.*)/gm, '<ol><li></li></ol>' ).replace(/<\/ol\>\n<ol\>/g, '\n' )
.replace(/\*\*\*(.*)\*\*\*/gm, '<b><em></em></b>')
.replace(/\*\*(.*)\*\*/gm, '<b></b>')
.replace(/\*([\w \d]*)\*/gm, '<em></em>')
.replace(/___(.*)___/gm, '<b><em></em></b>')
.replace(/__(.*)__/gm, '<u></u>')
.replace(/_([\w \d]*)_/gm, '<em></em>')
.replace(/~~(.*)~~/gm, '<del></del>')
.replace(/\^\^(.*)\^\^/gm, '<ins></ins>')
.replace(/ +\n/g, '\n<br/>')
.replace(/\n\s*\n/g, '\n<p>\n')
.replace(/^ {4,10}(.*)/gm, '<pre><code></code></pre>' )
.replace(/^\t(.*)/gm, '<pre><code></code></pre>' )
.replace(/<\/code\><\/pre\>\n<pre\><code\>/g, '\n' )
.replace(/\([`_\\*\+\-\.\(\)\[\]\{\}])/gm, '' )
}
}
return mdHTML.trim()
}
我用 Vue JS 做了一个小博客,它呈现带有标题和描述的帖子。我希望能够在描述中使用降价,所以我使用了 npm install marked
当我在数据中对文本进行硬编码时它工作正常,但试图传递我的描述本身来自道具时,它不起作用。
请参阅下面我的代码,我评论了哪些不起作用,并举了一个硬编码数据的例子。
知道如何解决这个问题吗?谢谢!
<template>
<div class="til-list">
<div v-for="til in tils" :key="til">
<div class="til">
<h3>{{ til.title }}</h3>
<p>{{ til.description }}</p>
<div v-html="markdownToHtml"></div>
<!-- <div v-html="markdownToHtml(til.description)"></div> -->
<span v-for="tag in til.tags" :key="tag"> #{{ tag }} </span>
</div>
</div>
</div>
</template>
<script>
import marked from "marked";
export default {
props: ["tils"],
// computed: {
// markdownToHtml(description) {
// return marked(this.description);
// },
// },
data() {
return {
markdown: "# Hello World",
};
},
computed: {
markdownToHtml() {
return marked(this.markdown);
},
},
};
</script>
尝试使用 methods
代替 computed
属性:
new Vue({
el: '#demo',
//props: ["tils"],
data() {
return {
tils: [{title: 'title 1', description: '<b>text</b>'}, {title: 'title 2', description: '<i>text</i>'}]
};
},
methods: {
markdownToHtml(description) {
return marked(description);
},
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
<div id="demo">
<div class="til-list">
<div v-for="(til, index) in tils" :key="index">
<div class="til">
<h3>{{ til.title }}</h3>
<p>{{ til.description }}</p>
<div v-html="markdownToHtml(til.description)"></div>
<!--<span v-for="tag in til.tags" :key="tag"> #{{ tag }} </span>-->
</div>
</div>
</div>
</div>
可以在纯 javascript 中尝试以下简单的解析器。 文档和详细信息可以在 https://github.com/casualwriter/powerpage-md-document
找到//=== simple markdown parser
function simpleMarkdown(mdText) {
// first, handle syntax for code-block
mdText = mdText.replace(/\r\n/g, '\n')
mdText = mdText.replace(/\n~~~ *(.*?)\n([\s\S]*?)\n~~~/g, '<pre><code title=""></code></pre>' )
mdText = mdText.replace(/\n``` *(.*?)\n([\s\S]*?)\n```/g, '<pre><code title=""></code></pre>' )
// split by "pre>", skip for code-block and process normal text
var mdHTML = ''
var mdCode = mdText.split( 'pre>')
for (var i=0; i<mdCode.length; i++) {
if ( mdCode[i].substr(-2) == '</' ) {
mdHTML += '<pre>' + mdCode[i] + 'pre>'
} else {
mdHTML += mdCode[i].replace(/(.*)<$/, '')
.replace(/^##### (.*?)\s*#*$/gm, '<h5></h5>')
.replace(/^#### (.*?)\s*#*$/gm, '<h4 id=""></h4>')
.replace(/^### (.*?)\s*#*$/gm, '<h3 id=""></h3>')
.replace(/^## (.*?)\s*#*$/gm, '<h2 id=""></h2>')
.replace(/^# (.*?)\s*#*$/gm, '<h1 id=""></h1>')
.replace(/^-{3,}|^\_{3,}|^\*{3,}/gm, '<hr/>')
.replace(/``(.*?)``/gm, '<code></code>' )
.replace(/`(.*?)`/gm, '<code></code>' )
.replace(/^\>> (.*$)/gm, '<blockquote><blockquote></blockquote></blockquote>')
.replace(/^\> (.*$)/gm, '<blockquote></blockquote>')
.replace(/<\/blockquote\>\n<blockquote\>/g, '\n<br>' )
.replace(/<\/blockquote\>\n<br\><blockquote\>/g, '\n<br>' )
.replace(/!\[(.*?)\]\((.*?) "(.*?)"\)/gm, '<img alt="" src="" />')
.replace(/!\[(.*?)\]\((.*?)\)/gm, '<img alt="" src="" />')
.replace(/\[(.*?)\]\((.*?) "(.*?)"\)/gm, '<a href="" title=""></a>')
.replace(/<http(.*?)\>/gm, '<a href="http">http</a>')
.replace(/\[(.*?)\]\(\)/gm, '<a href=""></a>')
.replace(/\[(.*?)\]\((.*?)\)/gm, '<a href=""></a>')
.replace(/^[\*|+|-][ |.](.*)/gm, '<ul><li></li></ul>' ).replace(/<\/ul\>\n<ul\>/g, '\n' )
.replace(/^\d[ |.](.*)/gm, '<ol><li></li></ol>' ).replace(/<\/ol\>\n<ol\>/g, '\n' )
.replace(/\*\*\*(.*)\*\*\*/gm, '<b><em></em></b>')
.replace(/\*\*(.*)\*\*/gm, '<b></b>')
.replace(/\*([\w \d]*)\*/gm, '<em></em>')
.replace(/___(.*)___/gm, '<b><em></em></b>')
.replace(/__(.*)__/gm, '<u></u>')
.replace(/_([\w \d]*)_/gm, '<em></em>')
.replace(/~~(.*)~~/gm, '<del></del>')
.replace(/\^\^(.*)\^\^/gm, '<ins></ins>')
.replace(/ +\n/g, '\n<br/>')
.replace(/\n\s*\n/g, '\n<p>\n')
.replace(/^ {4,10}(.*)/gm, '<pre><code></code></pre>' )
.replace(/^\t(.*)/gm, '<pre><code></code></pre>' )
.replace(/<\/code\><\/pre\>\n<pre\><code\>/g, '\n' )
.replace(/\([`_\\*\+\-\.\(\)\[\]\{\}])/gm, '' )
}
}
return mdHTML.trim()
}