add: markdown viewer

This commit is contained in:
alivender
2025-05-16 20:35:43 +08:00
parent 48ae3b5975
commit 7dd5e2189f
5 changed files with 428 additions and 9 deletions

View File

@@ -0,0 +1,207 @@
<script setup lang="ts">
import { computed } from 'vue';
import { marked } from 'marked';
const props = defineProps({
content: {
type: String,
required: true
}
});
const renderedContent = computed(() => {
if (!props.content) return '<p>没有内容</p>';
let processedContent = props.content;
// 设置 marked 选项
const renderer = new marked.Renderer();
marked.setOptions({
renderer: renderer,
gfm: true,
breaks: true
});
return marked(processedContent);
});
</script>
<template>
<div class="markdown-content" v-html="renderedContent"></div>
</template>
<style scoped>
.markdown-content {
color: hsl(var(--bc));
line-height: 1.6;
padding: 1rem 1.5rem;
max-width: 100%;
}
.markdown-content :deep(img) {
max-width: 60%;
height: auto;
display: block;
margin: 1rem auto;
border-radius: 0.5rem;
box-shadow: 0 1px 3px rgba(0,0,0,0.12);
}
.markdown-content :deep(h1) {
margin-top: 2rem;
margin-bottom: 1rem;
color: hsl(var(--bc));
font-weight: 700;
font-size: 2rem;
line-height: 1.3;
padding-bottom: 0.5rem;
border-bottom: 1px solid hsl(var(--b2));
}
.markdown-content :deep(h2) {
margin-top: 1.8rem;
margin-bottom: 0.8rem;
color: hsl(var(--bc));
font-weight: 600;
font-size: 1.5rem;
line-height: 1.4;
padding-left: 0.5rem;
border-left: 4px solid hsl(var(--p));
}
.markdown-content :deep(h3) {
margin-top: 1.5rem;
margin-bottom: 0.75rem;
color: hsl(var(--bc));
font-weight: 600;
font-size: 1.25rem;
line-height: 1.4;
padding-left: 1rem;
}
.markdown-content :deep(h4),
.markdown-content :deep(h5),
.markdown-content :deep(h6) {
margin-top: 1.2rem;
margin-bottom: 0.6rem;
color: hsl(var(--bc));
font-weight: 600;
font-size: 1.1rem;
line-height: 1.5;
padding-left: 1.5rem;
}
.markdown-content :deep(p) {
text-indent: 2em;
margin: 1rem 0;
color: hsl(var(--bc) / 0.8);
line-height: 1.8;
}
.markdown-content :deep(ul),
.markdown-content :deep(ol) {
padding-left: 2em;
margin: 0.75rem 0;
color: hsl(var(--bc) / 0.8);
}
.markdown-content :deep(li) {
margin: 0.4rem 0;
position: relative;
}
.markdown-content :deep(ul ul),
.markdown-content :deep(ul ol),
.markdown-content :deep(ol ul),
.markdown-content :deep(ol ol) {
margin: 0.4rem 0 0.4rem 1rem;
}
.markdown-content :deep(ul) {
list-style-type: disc;
}
.markdown-content :deep(ol) {
list-style-type: decimal;
}
.markdown-content :deep(ul ul) {
list-style-type: circle;
}
.markdown-content :deep(ul ul ul) {
list-style-type: square;
}
.markdown-content :deep(ul li::marker) {
color: hsl(var(--p));
}
.markdown-content :deep(pre) {
background-color: hsl(var(--b3));
padding: 1rem;
border-radius: 0.5rem;
overflow-x: auto;
border: 1px solid hsl(var(--b2));
margin: 1rem 0;
}
.markdown-content :deep(code) {
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
background-color: hsl(var(--b3));
padding: 2px 0.5rem;
border-radius: 0.25rem;
font-size: 0.9em;
color: hsl(var(--p));
}
.markdown-content :deep(table) {
border-collapse: collapse;
width: 100%;
margin: 1rem 0;
background-color: hsl(var(--b1));
border-radius: 0.5rem;
overflow: hidden;
box-shadow: 0 1px 3px rgba(0,0,0,0.12);
}
.markdown-content :deep(th),
.markdown-content :deep(td) {
border: 1px solid hsl(var(--b2));
padding: 0.75rem;
text-align: left;
}
.markdown-content :deep(th) {
background-color: hsl(var(--b2));
font-weight: 500;
color: hsl(var(--bc));
}
.markdown-content :deep(td) {
color: hsl(var(--bc) / 0.8);
}
.markdown-content :deep(blockquote) {
margin: 1rem 0;
padding: 0.5rem 1rem;
border-left: 4px solid hsl(var(--p));
background-color: hsl(var(--b2));
color: hsl(var(--bc) / 0.8);
font-style: italic;
}
.markdown-content :deep(hr) {
border: none;
border-top: 1px solid hsl(var(--b2));
margin: 1.5rem 0;
}
.markdown-content :deep(a) {
color: hsl(var(--p));
text-decoration: none;
transition: color 0.2s;
}
.markdown-content :deep(a:hover) {
color: hsl(var(--pf));
text-decoration: underline;
}
</style>