zero-markdown-view.vue 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312
  1. <template>
  2. <view class="zero-markdown-view">
  3. <mp-html :key="mpkey" :selectable="selectable" :scroll-table='scrollTable' :tag-style="tagStyle"
  4. :markdown="true" :content="contentAi">
  5. </mp-html>
  6. </view>
  7. </template>
  8. <script>
  9. import mpHtml from '../mp-html/mp-html';
  10. export default {
  11. name: 'zero-markdown-view',
  12. components: {
  13. mpHtml
  14. },
  15. props: {
  16. markdown: {
  17. type: String,
  18. default: ''
  19. },
  20. selectable: {
  21. type: [Boolean, String],
  22. default: true
  23. },
  24. scrollTable: {
  25. type: Boolean,
  26. default: true
  27. },
  28. themeColor: {
  29. type: String,
  30. default: '#007AFF'
  31. },
  32. codeBgColor: {
  33. type: String,
  34. default: '#2d2d2d'
  35. },
  36. aiMode: {
  37. type: Boolean,
  38. default: false
  39. }
  40. },
  41. data() {
  42. return {
  43. content: '',
  44. tagStyle: '',
  45. mpkey: 'zero'
  46. };
  47. },
  48. computed: {
  49. contentAi() {
  50. if (!this.content) {
  51. return //处理特殊情况,比如网络异常导致的响应的 content 的值为空
  52. }
  53. let htmlString = ''
  54. // 检查是否有未闭合的代码块
  55. const codeBlocks = this.content.match(/```[\s\S]*?```|```[\s\S]*?$/g) || []
  56. const lastBlock = codeBlocks[codeBlocks.length - 1]
  57. if (lastBlock && !lastBlock.endsWith('```')) {
  58. // 最后一个代码块未闭合,需要补上结束标识符
  59. htmlString = this.content + '\n'
  60. } else {
  61. htmlString = this.content
  62. }
  63. return htmlString
  64. },
  65. },
  66. watch: {
  67. markdown: function (val) {
  68. this.content = this.markdown
  69. }
  70. },
  71. created() {
  72. if (this.aiMode) {
  73. this.initTagStyleForAi();
  74. } else {
  75. this.initTagStyle();
  76. }
  77. },
  78. mounted() {
  79. this.content = this.markdown
  80. },
  81. methods: {
  82. initTagStyle() {
  83. const themeColor = this.themeColor
  84. const codeBgColor = this.codeBgColor
  85. let zeroStyle = {
  86. p: `
  87. margin:5px 5px;
  88. font-size: 15px;
  89. line-height:1.75;
  90. letter-spacing:0.2em;
  91. word-spacing:0.1em;
  92. `,
  93. // 一级标题
  94. h1: `
  95. margin:25px 0;
  96. font-size: 24px;
  97. text-align: center;
  98. font-weight: bold;
  99. color: ${themeColor};
  100. padding:3px 10px 1px;
  101. border-bottom: 2px solid ${themeColor};
  102. border-top-right-radius:3px;
  103. border-top-left-radius:3px;
  104. `,
  105. // 二级标题
  106. h2: `
  107. margin:40px 0 20px 0;
  108. font-size: 20px;
  109. text-align:center;
  110. color:${themeColor};
  111. font-weight:bolder;
  112. padding-left:10px;
  113. // border:1px solid ${themeColor};
  114. `,
  115. // 三级标题
  116. h3: `
  117. margin:30px 0 10px 0;
  118. font-size: 18px;
  119. color: ${themeColor};
  120. padding-left:10px;
  121. border-left:3px solid ${themeColor};
  122. `,
  123. // 引用
  124. blockquote: `
  125. margin:15px 0;
  126. font-size:15px;
  127. color: #777777;
  128. border-left: 4px solid #dddddd;
  129. padding: 0 10px;
  130. `,
  131. // 列表
  132. ul: `
  133. margin: 10px 0;
  134. color: #555;
  135. `,
  136. li: `
  137. margin: 5px 0;
  138. color: #555;
  139. `,
  140. // 链接
  141. a: `
  142. // color: ${themeColor};
  143. `,
  144. // 加粗
  145. strong: `
  146. font-weight: border;
  147. color: ${themeColor};
  148. `,
  149. // 斜体
  150. em: `
  151. color: ${themeColor};
  152. letter-spacing:0.3em;
  153. `,
  154. // 分割线
  155. hr: `
  156. height:1px;
  157. padding:0;
  158. border:none;
  159. text-align:center;
  160. background-image:linear-gradient(to right,rgba(248,57,41,0),${themeColor},rgba(248,57,41,0));
  161. margin:10px 0;
  162. `,
  163. // 表格
  164. table: `
  165. border-spacing:0;
  166. overflow:auto;
  167. min-width:100%;
  168. margin:10px 0;
  169. border-collapse: collapse;
  170. `,
  171. th: `
  172. border: 1px solid #202121;
  173. color: #555;
  174. `,
  175. td: `
  176. color:#555;
  177. border: 1px solid #555555;
  178. `,
  179. pre: `
  180. border-radius: 5px;
  181. white-space: pre;
  182. background: ${codeBgColor};
  183. font-size:12px;
  184. position: relative;
  185. `,
  186. }
  187. this.tagStyle = zeroStyle
  188. },
  189. initTagStyleForAi() {
  190. const themeColor = this.themeColor
  191. const codeBgColor = this.codeBgColor
  192. let zeroStyle = {
  193. p: `
  194. font-size: 16px;
  195. `,
  196. // 一级标题
  197. h1: `
  198. margin:18px 0 10px 0;
  199. font-size: 24px;
  200. color: ${themeColor};
  201. `,
  202. // 二级标题
  203. h2: `
  204. margin:14px 0 10px 0;
  205. font-size: 20px;
  206. color: ${themeColor};
  207. `,
  208. // 三级标题
  209. h3: `
  210. margin:12x 0 8px 0;
  211. font-size: 18px;
  212. color: ${themeColor};
  213. `,
  214. // 四级标题
  215. h4: `
  216. margin:12px 0 8px 0;
  217. font-size: 16px;
  218. color: ${themeColor};
  219. `,
  220. // 五级标题
  221. h5: `
  222. margin:10px 0 8px 0;
  223. font-size: 16px;
  224. color: ${themeColor};
  225. `,
  226. // 六级标题
  227. h6: `
  228. margin:8px 0 8px 0;
  229. font-size: 16px;
  230. color: ${themeColor}
  231. `,
  232. // 引用
  233. blockquote: `
  234. margin:15px 0;
  235. font-size:15px;
  236. color: #777777;
  237. border-left: 4px solid #dddddd;
  238. padding: 0 10px;
  239. `,
  240. // 列表
  241. ul: `
  242. margin: 10px 0;
  243. color: #555;
  244. `,
  245. li: `
  246. margin: 5px 0;
  247. color: #555;
  248. `,
  249. // 链接
  250. a: `
  251. // color: ${themeColor};
  252. `,
  253. // 加粗
  254. strong: `
  255. font-weight: border;
  256. color: ${themeColor};
  257. `,
  258. // 斜体
  259. em: `
  260. color: ${themeColor};
  261. letter-spacing:0.3em;
  262. `,
  263. // 分割线
  264. hr: `
  265. height:1px;
  266. padding:0;
  267. border:none;
  268. text-align:center;
  269. background-image:linear-gradient(to right,rgba(248,57,41,0),${themeColor},rgba(248,57,41,0));
  270. margin:10px 0;
  271. `,
  272. // 表格
  273. table: `
  274. border-spacing:0;
  275. overflow:auto;
  276. min-width:100%;
  277. margin:10px 0;
  278. border-collapse: collapse;
  279. `,
  280. th: `
  281. border: 1px solid #202121;
  282. color: #555;
  283. `,
  284. td: `
  285. color:#555;
  286. border: 1px solid #555555;
  287. `,
  288. pre: `
  289. border-radius: 5px;
  290. white-space: pre;
  291. background: ${codeBgColor};
  292. font-size:12px;
  293. position: relative;
  294. `,
  295. }
  296. this.tagStyle = zeroStyle
  297. },
  298. }
  299. };
  300. </script>
  301. <style lang="scss">
  302. .zero-markdown-view {
  303. padding: 15rpx;
  304. position: relative;
  305. }
  306. </style>