Files
jczxw-pc/app/components/admin/MarkdownRenderer.vue
2026-04-23 16:30:57 +08:00

172 lines
3.1 KiB
Vue

<template>
<div class="markdown-renderer" v-html="renderedHtml"></div>
</template>
<script setup lang="ts">
import { marked } from 'marked'
import hljs from 'highlight.js'
import 'highlight.js/styles/github.css'
interface Props {
content: string
}
const props = defineProps<Props>()
// 配置 marked
marked.setOptions({
highlight: function(code: string, lang: string) {
if (lang && hljs.getLanguage(lang)) {
return hljs.highlight(code, { language: lang }).value
}
return hljs.highlightAuto(code).value
},
breaks: true,
gfm: true,
})
const renderedHtml = computed(() => {
if (!props.content) return ''
try {
return marked.parse(props.content) as string
} catch (e) {
return '<p>渲染出错</p>'
}
})
</script>
<style scoped>
.markdown-renderer {
font-size: 15px;
line-height: 1.8;
color: rgba(0, 0, 0, 0.85);
}
.markdown-renderer :deep(h1) {
font-size: 1.8em;
font-weight: 700;
margin: 0.5em 0;
padding-bottom: 0.3em;
border-bottom: 1px solid #eaecef;
}
.markdown-renderer :deep(h2) {
font-size: 1.5em;
font-weight: 600;
margin: 0.8em 0 0.4em;
padding-bottom: 0.25em;
border-bottom: 1px solid #eaecef;
}
.markdown-renderer :deep(h3) {
font-size: 1.25em;
font-weight: 600;
margin: 0.6em 0 0.3em;
}
.markdown-renderer :deep(h4),
.markdown-renderer :deep(h5),
.markdown-renderer :deep(h6) {
font-weight: 600;
margin: 0.5em 0;
}
.markdown-renderer :deep(p) {
margin: 0.8em 0;
}
.markdown-renderer :deep(code) {
padding: 0.2em 0.4em;
background: #f6f8fa;
border-radius: 4px;
font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
font-size: 0.9em;
}
.markdown-renderer :deep(pre) {
padding: 16px;
background: #f6f8fa;
border-radius: 8px;
overflow-x: auto;
margin: 1em 0;
}
.markdown-renderer :deep(pre code) {
padding: 0;
background: transparent;
font-size: 0.9em;
}
.markdown-renderer :deep(blockquote) {
margin: 1em 0;
padding: 0.5em 1em;
border-left: 4px solid #dfe2e5;
color: #6a737d;
background: #f6f8fa;
border-radius: 0 8px 8px 0;
}
.markdown-renderer :deep(blockquote p) {
margin: 0.3em 0;
}
.markdown-renderer :deep(ul),
.markdown-renderer :deep(ol) {
padding-left: 2em;
margin: 0.8em 0;
}
.markdown-renderer :deep(li) {
margin: 0.3em 0;
}
.markdown-renderer :deep(a) {
color: #1890ff;
text-decoration: none;
}
.markdown-renderer :deep(a:hover) {
text-decoration: underline;
}
.markdown-renderer :deep(img) {
max-width: 100%;
border-radius: 8px;
margin: 1em 0;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
.markdown-renderer :deep(hr) {
margin: 1.5em 0;
border: none;
border-top: 1px solid #dfe2e5;
}
.markdown-renderer :deep(table) {
width: 100%;
border-collapse: collapse;
margin: 1em 0;
border-radius: 8px;
overflow: hidden;
}
.markdown-renderer :deep(th),
.markdown-renderer :deep(td) {
padding: 10px 14px;
border: 1px solid #dfe2e5;
}
.markdown-renderer :deep(th) {
background: #f6f8fa;
font-weight: 600;
}
.markdown-renderer :deep(tr:hover) {
background: #fafafa;
}
.markdown-renderer :deep(input[type="checkbox"]) {
margin-right: 0.5em;
}
</style>