index.vue 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. <template>
  2. <div ref="contentRef" class="markdown-view" v-html="renderedMarkdown"></div>
  3. </template>
  4. <script setup lang="ts">
  5. import { useClipboard } from '@vueuse/core'
  6. import MarkdownIt from 'markdown-it'
  7. import 'highlight.js/styles/vs2015.min.css'
  8. import hljs from 'highlight.js'
  9. // 定义组件属性
  10. const props = defineProps({
  11. content: {
  12. type: String,
  13. required: true
  14. }
  15. })
  16. const message = useMessage() // 消息弹窗
  17. const { copy } = useClipboard() // 初始化 copy 到粘贴板
  18. const contentRef = ref()
  19. const md = new MarkdownIt({
  20. highlight: function (str, lang) {
  21. if (lang && hljs.getLanguage(lang)) {
  22. try {
  23. const copyHtml = `<div id="copy" data-copy='${str}' style="position: absolute; right: 10px; top: 5px; color: #fff;cursor: pointer;">复制</div>`
  24. return `<pre style="position: relative;">${copyHtml}<code class="hljs">${hljs.highlight(lang, str, true).value}</code></pre>`
  25. } catch (__) {}
  26. }
  27. return ``
  28. }
  29. })
  30. /** 渲染 markdown */
  31. const renderedMarkdown = computed(() => {
  32. return md.render(props.content)
  33. })
  34. /** 初始化 **/
  35. onMounted(async () => {
  36. // 添加 copy 监听
  37. contentRef.value.addEventListener('click', (e: any) => {
  38. if (e.target.id === 'copy') {
  39. copy(e.target?.dataset?.copy)
  40. message.success('复制成功!')
  41. }
  42. })
  43. })
  44. </script>
  45. <style lang="scss">
  46. .markdown-view {
  47. font-family: PingFang SC;
  48. font-size: 0.95rem;
  49. font-weight: 400;
  50. line-height: 1.6rem;
  51. letter-spacing: 0em;
  52. text-align: left;
  53. color: #3b3e55;
  54. max-width: 100%;
  55. pre {
  56. position: relative;
  57. }
  58. pre code.hljs {
  59. width: auto;
  60. }
  61. code.hljs {
  62. border-radius: 6px;
  63. padding-top: 20px;
  64. width: auto;
  65. @media screen and (min-width: 1536px) {
  66. width: 960px;
  67. }
  68. @media screen and (max-width: 1536px) and (min-width: 1024px) {
  69. width: calc(100vw - 400px - 64px - 32px * 2);
  70. }
  71. @media screen and (max-width: 1024px) and (min-width: 768px) {
  72. width: calc(100vw - 32px * 2);
  73. }
  74. @media screen and (max-width: 768px) {
  75. width: calc(100vw - 16px * 2);
  76. }
  77. }
  78. p,
  79. code.hljs {
  80. margin-bottom: 16px;
  81. }
  82. p {
  83. //margin-bottom: 1rem !important;
  84. margin: 0;
  85. margin-bottom: 3px;
  86. }
  87. /* 标题通用格式 */
  88. h1,
  89. h2,
  90. h3,
  91. h4,
  92. h5,
  93. h6 {
  94. color: var(--color-G900);
  95. margin: 24px 0 8px;
  96. font-weight: 600;
  97. }
  98. h1 {
  99. font-size: 22px;
  100. line-height: 32px;
  101. }
  102. h2 {
  103. font-size: 20px;
  104. line-height: 30px;
  105. }
  106. h3 {
  107. font-size: 18px;
  108. line-height: 28px;
  109. }
  110. h4 {
  111. font-size: 16px;
  112. line-height: 26px;
  113. }
  114. h5 {
  115. font-size: 16px;
  116. line-height: 24px;
  117. }
  118. h6 {
  119. font-size: 16px;
  120. line-height: 24px;
  121. }
  122. /* 列表(有序,无序) */
  123. ul,
  124. ol {
  125. margin: 0 0 8px 0;
  126. padding: 0;
  127. font-size: 16px;
  128. line-height: 24px;
  129. color: #3b3e55; // var(--color-CG600);
  130. }
  131. li {
  132. margin: 4px 0 0 20px;
  133. margin-bottom: 1rem;
  134. }
  135. ol > li {
  136. list-style-type: decimal;
  137. margin-bottom: 1rem;
  138. // 表达式,修复有序列表序号展示不全的问题
  139. // &:nth-child(n + 10) {
  140. // margin-left: 30px;
  141. // }
  142. // &:nth-child(n + 100) {
  143. // margin-left: 30px;
  144. // }
  145. }
  146. ul > li {
  147. list-style-type: disc;
  148. font-size: 16px;
  149. line-height: 24px;
  150. margin-right: 11px;
  151. margin-bottom: 1rem;
  152. color: #3b3e55; // var(--color-G900);
  153. }
  154. ol ul,
  155. ol ul > li,
  156. ul ul,
  157. ul ul li {
  158. // list-style: circle;
  159. font-size: 16px;
  160. list-style: none;
  161. margin-left: 6px;
  162. margin-bottom: 1rem;
  163. }
  164. ul ul ul,
  165. ul ul ul li,
  166. ol ol,
  167. ol ol > li,
  168. ol ul ul,
  169. ol ul ul > li,
  170. ul ol,
  171. ul ol > li {
  172. list-style: square;
  173. }
  174. }
  175. </style>