-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMarkdownView.vue
75 lines (67 loc) · 2.28 KB
/
MarkdownView.vue
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
<template>
<article class="prose prose-code:before:content-none
prose-code:after:content-none
max-w-none min-w-80 prose-pre:bg-base-100 prose-pre:p-4
prose-pre:rounded-lg prose-pre:text-base-content">
<div v-html="renderContent()"></div>
</article>
</template>
<script setup lang="ts">
import { nextTick } from 'vue'
import MarkdownIt from 'markdown-it'
import hljs from 'highlight.js';
import 'highlight.js/styles/github.css'
const props = defineProps<{
content: string
}>()
// 添加复制功能
function setupCopyButtons() {
nextTick(() => {
const copyButtons = document.querySelectorAll('.copy-button')
copyButtons.forEach(button => {
button.addEventListener('click', async (e) => {
const codeBlock = (e.target as HTMLElement)
.closest('.code-block')
?.querySelector('code')
if (codeBlock) {
try {
await navigator.clipboard.writeText(codeBlock.textContent || '')
const btn = e.target as HTMLElement
btn.textContent = '已复制!'
setTimeout(() => {
btn.textContent = '复制'
}, 2000)
} catch (err) {
console.error('复制失败:', err)
}
}
})
})
})
}
// 修改高亮函数部分
const md: MarkdownIt = new MarkdownIt({
highlight: function (str: string, lang: string) {
if (lang && hljs.getLanguage(lang)) {
try {
const copyButton = `<button class="copy-button text-blue-500 hover:text-blue-700 transition-colors">复制</button>`;
const languageTitle = `<div class="flex justify-between items-center bg-base-200 px-4 py-2 text-sm font-mono rounded-t-lg">${lang}${copyButton}</div>`;
return `<div class="code-block">${languageTitle}<pre class="hljs my-0 rounded-t-none"><code>${hljs.highlight(str, { language: lang, ignoreIllegals: true }).value}</code></pre></div>`;
} catch (error) {
console.warn(`语法高亮错误: ${error}`)
}
}
return `<pre class="hljs"><code>${md.utils.escapeHtml(str)}</code></pre>`;
},
html: true,
linkify: true,
breaks: true
})
const renderContent = () => {
const html = md.render(props.content)
// 在内容渲染后设置复制按钮
setupCopyButtons()
return html
}
</script>
<style scoped></style>