feat: code block dark mode
This commit is contained in:
parent
6d640e8049
commit
cc83133a6c
|
@ -1,9 +1,11 @@
|
|||
<script setup lang="ts">
|
||||
import { computed, onMounted } from 'vue';
|
||||
import { computed, onMounted, ref, watch } from 'vue';
|
||||
import { marked } from 'marked';
|
||||
import hljs from 'highlight.js';
|
||||
// 导入默认样式 - 选择一个适合你的主题
|
||||
import 'highlight.js/styles/github-dark.css';
|
||||
// 导入亮色主题样式
|
||||
import 'highlight.js/styles/github.css'; // 亮色主题
|
||||
// 导入主题存储
|
||||
import { useThemeStore } from '@/stores/theme';
|
||||
|
||||
const props = defineProps({
|
||||
content: {
|
||||
|
@ -16,6 +18,24 @@ const props = defineProps({
|
|||
}
|
||||
});
|
||||
|
||||
// 使用主题存储
|
||||
const themeStore = useThemeStore();
|
||||
// 使用 isDarkTheme 函数来检查当前是否为暗色主题
|
||||
const isDarkMode = computed(() => themeStore.isDarkTheme());
|
||||
|
||||
// 监听主题变化
|
||||
watch(() => themeStore.currentTheme, () => {
|
||||
// 主题变化时更新代码高亮样式
|
||||
updateCodeBlocksTheme();
|
||||
});
|
||||
|
||||
// 更新代码块主题样式
|
||||
const updateCodeBlocksTheme = () => {
|
||||
// 这个函数可以在需要时手动更新代码块的样式
|
||||
// 由于我们使用CSS变量控制样式,可能不需要特定实现
|
||||
// 但如果需要,可以在这里添加额外逻辑
|
||||
};
|
||||
|
||||
const renderedContent = computed(() => {
|
||||
if (!props.content) return '<p>没有内容</p>';
|
||||
|
||||
|
@ -57,15 +77,14 @@ const renderedContent = computed(() => {
|
|||
return marked(processedContent);
|
||||
});
|
||||
|
||||
// 页面挂载后,对已渲染的代码块应用高亮效果
|
||||
// 页面挂载后,确保应用正确的主题样式
|
||||
onMounted(() => {
|
||||
// 如果需要在客户端重新高亮(通常不需要,因为我们已经在服务端高亮)
|
||||
// hljs.highlightAll();
|
||||
updateCodeBlocksTheme();
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="markdown-content" v-html="renderedContent"></div>
|
||||
<div class="markdown-content" :data-theme="themeStore.currentTheme" v-html="renderedContent"></div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
@ -208,9 +227,9 @@ onMounted(() => {
|
|||
color: hsl(var(--s));
|
||||
}
|
||||
|
||||
/* 代码块样式增强 */
|
||||
/* 代码块样式增强 - 响应主题 */
|
||||
.markdown-content :deep(pre) {
|
||||
background-color: hsl(var(--b3));
|
||||
background-color: var(--code-bg, hsl(var(--b2)));
|
||||
padding: 1rem;
|
||||
border-radius: 0.5rem;
|
||||
overflow-x: auto;
|
||||
|
@ -218,6 +237,7 @@ onMounted(() => {
|
|||
margin: 1.5rem 0;
|
||||
box-shadow: 0 4px 8px rgba(0,0,0,0.1);
|
||||
position: relative;
|
||||
color: var(--code-color, hsl(var(--bc)));
|
||||
}
|
||||
|
||||
.markdown-content :deep(pre::before) {
|
||||
|
@ -233,14 +253,13 @@ onMounted(() => {
|
|||
|
||||
/* 代码语言标签 */
|
||||
.markdown-content :deep(pre.hljs::after) {
|
||||
content: attr(class);
|
||||
content: attr(data-language);
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
color: hsl(var(--bc) / 0.7);
|
||||
color: var(--code-label-color, hsl(var(--bc) / 0.7));
|
||||
font-size: 0.75rem;
|
||||
background-color: hsl(var(--b2));
|
||||
background-color: var(--code-label-bg, hsl(var(--b3)));
|
||||
padding: 0.2rem 0.5rem;
|
||||
border-radius: 0 0.3rem 0 0.3rem;
|
||||
opacity: 0.8;
|
||||
|
@ -249,11 +268,11 @@ onMounted(() => {
|
|||
/* 内联代码样式 */
|
||||
.markdown-content :deep(code) {
|
||||
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
||||
background-color: hsl(var(--b3) / 0.7);
|
||||
background-color: var(--inline-code-bg, hsl(var(--b3) / 0.7));
|
||||
padding: 0.2rem 0.5rem;
|
||||
border-radius: 0.25rem;
|
||||
font-size: 0.9em;
|
||||
color: hsl(var(--p));
|
||||
color: var(--inline-code-color, hsl(var(--p)));
|
||||
border: 1px solid hsl(var(--b2) / 0.5);
|
||||
}
|
||||
|
||||
|
@ -389,6 +408,235 @@ onMounted(() => {
|
|||
text-decoration: underline;
|
||||
}
|
||||
|
||||
/* 亮色主题下的代码样式 */
|
||||
:root[data-theme="winter"] .markdown-content :deep(.hljs),
|
||||
.markdown-content[data-theme="winter"] :deep(.hljs),
|
||||
[data-theme="winter"] .markdown-content :deep(.hljs) {
|
||||
--code-bg: #f5f7ff;
|
||||
--code-color: #333;
|
||||
--inline-code-bg: #f0f2fa;
|
||||
--inline-code-color: #d32f2f;
|
||||
--code-label-bg: #e6e9f5;
|
||||
--code-label-color: #666;
|
||||
}
|
||||
|
||||
/* 亮色主题下的语法高亮 */
|
||||
:root[data-theme="winter"] .markdown-content :deep(.hljs-keyword),
|
||||
.markdown-content[data-theme="winter"] :deep(.hljs-keyword),
|
||||
[data-theme="winter"] .markdown-content :deep(.hljs-keyword),
|
||||
:root[data-theme="winter"] .markdown-content :deep(.hljs-tag),
|
||||
.markdown-content[data-theme="winter"] :deep(.hljs-tag),
|
||||
[data-theme="winter"] .markdown-content :deep(.hljs-tag),
|
||||
:root[data-theme="winter"] .markdown-content :deep(.hljs-selector-tag),
|
||||
.markdown-content[data-theme="winter"] :deep(.hljs-selector-tag),
|
||||
[data-theme="winter"] .markdown-content :deep(.hljs-selector-tag) {
|
||||
color: #8959a8; /* 紫色,用于关键字 */
|
||||
}
|
||||
|
||||
:root[data-theme="winter"] .markdown-content :deep(.hljs-string),
|
||||
.markdown-content[data-theme="winter"] :deep(.hljs-string),
|
||||
[data-theme="winter"] .markdown-content :deep(.hljs-string),
|
||||
:root[data-theme="winter"] .markdown-content :deep(.hljs-regexp),
|
||||
.markdown-content[data-theme="winter"] :deep(.hljs-regexp),
|
||||
[data-theme="winter"] .markdown-content :deep(.hljs-regexp) {
|
||||
color: #2e7d32; /* 绿色,用于字符串 */
|
||||
}
|
||||
|
||||
:root[data-theme="winter"] .markdown-content :deep(.hljs-number),
|
||||
.markdown-content[data-theme="winter"] :deep(.hljs-number),
|
||||
[data-theme="winter"] .markdown-content :deep(.hljs-number),
|
||||
:root[data-theme="winter"] .markdown-content :deep(.hljs-literal),
|
||||
.markdown-content[data-theme="winter"] :deep(.hljs-literal),
|
||||
[data-theme="winter"] .markdown-content :deep(.hljs-literal) {
|
||||
color: #f5871f; /* 橙色,用于数字 */
|
||||
}
|
||||
|
||||
:root[data-theme="winter"] .markdown-content :deep(.hljs-comment),
|
||||
.markdown-content[data-theme="winter"] :deep(.hljs-comment),
|
||||
[data-theme="winter"] .markdown-content :deep(.hljs-comment) {
|
||||
color: #8e908c; /* 灰色,用于注释 */
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
:root[data-theme="winter"] .markdown-content :deep(.hljs-built_in),
|
||||
.markdown-content[data-theme="winter"] :deep(.hljs-built_in),
|
||||
[data-theme="winter"] .markdown-content :deep(.hljs-built_in) {
|
||||
color: #3e999f; /* 青色,用于内置函数 */
|
||||
}
|
||||
|
||||
:root[data-theme="winter"] .markdown-content :deep(.hljs-title),
|
||||
.markdown-content[data-theme="winter"] :deep(.hljs-title),
|
||||
[data-theme="winter"] .markdown-content :deep(.hljs-title),
|
||||
:root[data-theme="winter"] .markdown-content :deep(.hljs-function),
|
||||
.markdown-content[data-theme="winter"] :deep(.hljs-function),
|
||||
[data-theme="winter"] .markdown-content :deep(.hljs-function) {
|
||||
color: #4271ae; /* 蓝色,用于函数名 */
|
||||
}
|
||||
|
||||
:root[data-theme="winter"] .markdown-content :deep(.hljs-name),
|
||||
.markdown-content[data-theme="winter"] :deep(.hljs-name),
|
||||
[data-theme="winter"] .markdown-content :deep(.hljs-name),
|
||||
:root[data-theme="winter"] .markdown-content :deep(.hljs-attribute),
|
||||
.markdown-content[data-theme="winter"] :deep(.hljs-attribute),
|
||||
[data-theme="winter"] .markdown-content :deep(.hljs-attribute) {
|
||||
color: #c82829; /* 红色,用于HTML标签和属性 */
|
||||
}
|
||||
|
||||
/* 暗黑主题下的代码样式 */
|
||||
:root[data-theme="night"] .markdown-content :deep(.hljs),
|
||||
.markdown-content[data-theme="night"] :deep(.hljs),
|
||||
[data-theme="night"] .markdown-content :deep(.hljs) {
|
||||
--code-bg: #1e1e2e;
|
||||
--code-color: #f8f8f2;
|
||||
--inline-code-bg: #282a36;
|
||||
--inline-code-color: #ff79c6;
|
||||
--code-label-bg: #282a36;
|
||||
--code-label-color: #bd93f9;
|
||||
}
|
||||
|
||||
/* 暗黑主题下的语法高亮 */
|
||||
:root[data-theme="night"] .markdown-content :deep(.hljs-keyword),
|
||||
.markdown-content[data-theme="night"] :deep(.hljs-keyword),
|
||||
[data-theme="night"] .markdown-content :deep(.hljs-keyword),
|
||||
:root[data-theme="night"] .markdown-content :deep(.hljs-tag),
|
||||
.markdown-content[data-theme="night"] :deep(.hljs-tag),
|
||||
[data-theme="night"] .markdown-content :deep(.hljs-tag),
|
||||
:root[data-theme="night"] .markdown-content :deep(.hljs-selector-tag),
|
||||
.markdown-content[data-theme="night"] :deep(.hljs-selector-tag),
|
||||
[data-theme="night"] .markdown-content :deep(.hljs-selector-tag) {
|
||||
color: #cc99cd; /* 紫色,用于关键字 */
|
||||
}
|
||||
|
||||
:root[data-theme="night"] .markdown-content :deep(.hljs-string),
|
||||
.markdown-content[data-theme="night"] :deep(.hljs-string),
|
||||
[data-theme="night"] .markdown-content :deep(.hljs-string),
|
||||
:root[data-theme="night"] .markdown-content :deep(.hljs-regexp),
|
||||
.markdown-content[data-theme="night"] :deep(.hljs-regexp),
|
||||
[data-theme="night"] .markdown-content :deep(.hljs-regexp) {
|
||||
color: #7ec699; /* 绿色,用于字符串 */
|
||||
}
|
||||
|
||||
:root[data-theme="night"] .markdown-content :deep(.hljs-number),
|
||||
.markdown-content[data-theme="night"] :deep(.hljs-number),
|
||||
[data-theme="night"] .markdown-content :deep(.hljs-number),
|
||||
:root[data-theme="night"] .markdown-content :deep(.hljs-literal),
|
||||
.markdown-content[data-theme="night"] :deep(.hljs-literal),
|
||||
[data-theme="night"] .markdown-content :deep(.hljs-literal) {
|
||||
color: #f08d49; /* 橙色,用于数字 */
|
||||
}
|
||||
|
||||
:root[data-theme="night"] .markdown-content :deep(.hljs-comment),
|
||||
.markdown-content[data-theme="night"] :deep(.hljs-comment),
|
||||
[data-theme="night"] .markdown-content :deep(.hljs-comment) {
|
||||
color: #999999; /* 灰色,用于注释 */
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
:root[data-theme="night"] .markdown-content :deep(.hljs-built_in),
|
||||
.markdown-content[data-theme="night"] :deep(.hljs-built_in),
|
||||
[data-theme="night"] .markdown-content :deep(.hljs-built_in) {
|
||||
color: #6196cc; /* 蓝色,用于内置函数 */
|
||||
}
|
||||
|
||||
:root[data-theme="night"] .markdown-content :deep(.hljs-title),
|
||||
.markdown-content[data-theme="night"] :deep(.hljs-title),
|
||||
[data-theme="night"] .markdown-content :deep(.hljs-title),
|
||||
:root[data-theme="night"] .markdown-content :deep(.hljs-function),
|
||||
.markdown-content[data-theme="night"] :deep(.hljs-function),
|
||||
[data-theme="night"] .markdown-content :deep(.hljs-function) {
|
||||
color: #f8c555; /* 金色,用于函数名 */
|
||||
}
|
||||
|
||||
:root[data-theme="night"] .markdown-content :deep(.hljs-name),
|
||||
.markdown-content[data-theme="night"] :deep(.hljs-name),
|
||||
[data-theme="night"] .markdown-content :deep(.hljs-name),
|
||||
:root[data-theme="night"] .markdown-content :deep(.hljs-attribute),
|
||||
.markdown-content[data-theme="night"] :deep(.hljs-attribute),
|
||||
[data-theme="night"] .markdown-content :deep(.hljs-attribute) {
|
||||
color: #e2777a; /* 红色,用于HTML标签和属性 */
|
||||
}
|
||||
|
||||
.markdown-content :deep(table) {
|
||||
border-collapse: separate;
|
||||
border-spacing: 0;
|
||||
width: 100%;
|
||||
margin: 1.5rem 0;
|
||||
background-color: hsl(var(--b1));
|
||||
border-radius: 0.5rem;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 2px 8px rgba(0,0,0,0.08);
|
||||
border: 1px solid hsl(var(--b2));
|
||||
}
|
||||
|
||||
.markdown-content :deep(th),
|
||||
.markdown-content :deep(td) {
|
||||
border: 1px solid hsl(var(--b2));
|
||||
padding: 0.75rem 1rem;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.markdown-content :deep(th) {
|
||||
background-color: hsl(var(--p) / 0.15);
|
||||
font-weight: 600;
|
||||
color: hsl(var(--bc));
|
||||
border-bottom: 2px solid hsl(var(--p) / 0.5);
|
||||
}
|
||||
|
||||
.markdown-content :deep(tr:nth-child(even)) {
|
||||
background-color: hsl(var(--b2) / 0.3);
|
||||
}
|
||||
|
||||
.markdown-content :deep(tr:hover) {
|
||||
background-color: hsl(var(--b2) / 0.5);
|
||||
}
|
||||
|
||||
.markdown-content :deep(td) {
|
||||
color: hsl(var(--bc) / 0.8);
|
||||
}
|
||||
|
||||
.markdown-content :deep(blockquote) {
|
||||
margin: 1.5rem 0;
|
||||
padding: 1rem 1.5rem;
|
||||
border-left: 4px solid hsl(var(--p));
|
||||
background-color: hsl(var(--b2) / 0.3);
|
||||
color: hsl(var(--bc) / 0.9);
|
||||
font-style: italic;
|
||||
border-radius: 0 0.5rem 0.5rem 0;
|
||||
box-shadow: 0 2px 5px rgba(0,0,0,0.03);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.markdown-content :deep(blockquote::before) {
|
||||
content: '"';
|
||||
font-size: 2rem;
|
||||
color: hsl(var(--p) / 0.3);
|
||||
position: absolute;
|
||||
top: 0.5rem;
|
||||
left: 0.5rem;
|
||||
font-family: serif;
|
||||
}
|
||||
|
||||
.markdown-content :deep(blockquote p) {
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
|
||||
.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;
|
||||
}
|
||||
|
||||
/* 暗黑模式下的代码高亮调整 */
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.markdown-content :deep(pre) {
|
||||
|
|
Loading…
Reference in New Issue