第一步:下载marked和代码块高亮highlight.js
- npm i marked
-
- npm i highlight.js
-
- npm i markdown-loader
-
- npm i github-markdown-css
第二步:注册并使用
main.js
- import hljs from "highlight.js";
- import "github-markdown-css";
- import "highlight.js/styles/atom-one-dark.css";
-
- Vue.directive("highlight", function (el) {
- let blocks = el.querySelectorAll("pre code");
- blocks.forEach((block) => {
- hljs.highlightBlock(block);
- });
- });
页面内使用
1、其中class的markdown-body是必须要带的,marked的样式,同时如果需要修改样式,也可以通过此修改
2、v-highlight全局注册代码块高亮
3、自定义渲染器我是需要改变标题转换,如果你们有需要可以自行处理
- <template>
- <div id="Mindopt" class="Mindopt">
- <div v-highlight class="replybox markdown-body" v-html="Mindoptinfo">div>
- div>
- template>
-
- <script>
- // 创建自定义渲染器
- class CustomRenderer extends marked.Renderer {
- heading (text, level) {
- // 将一级标题转换为h1标签
- if (level === 1) {
- return `
# ${text}
`; - } else if (level === 2) {
- return `
## ${text}
`; - } else if (level === 3) {
- return `
### ${text}
`; - } else if (level === 4) {
- return `
#### ${text}
`; - } else if (level === 5) {
- return `
##### ${text}
`; - } else if (level === 6) {
- return `
###### ${text}
`; - }
- }
- // text (text) {
- // console.log(text);
- // }
- // code (code, language, isEscaped) {
- // console.log(language);
- // if (language && language === 'math') {
- // return katex.renderToString(code, { throwOnError: false });
- // }
- // return marked.Renderer.prototype.code.call(renderer, code, language, isEscaped);
- // };
- }
- // 使用自定义渲染器
- const renderer = new CustomRenderer();
- const markedOptions = {
- renderer: renderer,
- breaks: true,
- };
- import { marked } from "marked";
- import { getoptInfo, getGroupMessage, updataGroup, deleteGroupMessages } from '@/api/Mindopt'
- export default {
- name: 'Mindopt',
- data () {
- return {
- Mindoptinfo: '',
- }
- },
- created () {
- this.getoptInfo()
- },
- methods: {
- // 获取信息
- async getoptInfo () {
- const res = await getoptInfo()
- this.Mindoptinfo = res.data
- this.Mindoptinfo = marked(this.Mindoptinfo, markedOptions);
- },
- }
- }
- script>
-
-
- <style lang="scss">
- // 回答的格式或者数据回显的格式
- .markdown-body {
- // font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB,
- // Microsoft YaHei, Arial, sans-serif !important;
- // line-height: 20px;
-
- // & ul {
- // list-style: none;
- // padding-left: 20px;
- // }
-
- color: #000 !important;
-
- p {
- margin-top: 10px !important;
- margin-bottom: 10px !important;
- }
-
- pre {
- padding: 5px !important;
- margin-bottom: 10px !important;
- }
-
- .hljs {
- color: #abb2bf;
- background: #282c34;
- }
-
- .hClass {
- //出现#则不转换为h1等标签
- font-size: 16px;
- color: #8a2328;
- font-weight: 600;
- margin: 10px 0;
- }
-
- /* 只改变普通 code 标签的颜色,不影响 pre 中的 code */
- code:not(pre) {
- color: red;
- font-weight: 600;
- background-color: rgba(175, 184, 193, 0.3);
- margin: 0 5px;
- }
-
- a {
- color: #1d71f7 !important;
- }
- }
- style>
页面使用
- <template>
- <div id="Mindopt" class="Mindopt">
- <div v-highlight class="replybox markdown-body" v-html="Mindoptinfo">div>
- div>
- template>
-
- <script>
- import CodeCopy from './CodeCopy.vue'
- export default {
- name: 'Mindopt',
- data () {
- return {
- Mindoptinfo: '',
- }
- },
- updated () {
- this.update()
- },
- methods: {
- //获取对应markdown代码块标签
- update () {
- setTimeout(() => {
- // 代码块添加复制按钮
- document.querySelectorAll('pre').forEach(el => {
- // console.log(el)
- if (el.classList.contains('code-copy-added')) return
- // https://cn.vuejs.org/v2/api/index.html#Vue-extend
- /* 使用基础 Vue 构造器,创建一个“子类”。参数是一个包含组件选项的对象 */
- let ComponentClass = Vue.extend(CodeCopy)
- let instance = new ComponentClass()
- instance.code = el.innerText
- instance.parent = el
- /* 手动挂载 */
- instance.$mount()
- el.classList.add('code-copy-added')
- el.appendChild(instance.$el)
- })
- // 块引用添加复制按钮
- document.querySelectorAll('blockquote').forEach(el => {
- // console.log(el)
- if (el.classList.contains('code-copy-added')) return
- // https://cn.vuejs.org/v2/api/index.html#Vue-extend
- /* 使用基础 Vue 构造器,创建一个“子类”。参数是一个包含组件选项的对象 */
- let ComponentClass = Vue.extend(CodeCopy)
- let instance = new ComponentClass()
- instance.code = el.innerText
- instance.parent = el
- /* 手动挂载 */
- instance.$mount()
- el.classList.add('code-copy-added')
- el.appendChild(instance.$el)
- })
- }, 100)
- },
- }
- }
- script>
-
-
- <style lang="scss">
- // 复制按钮
- .codeContent {
- max-width: 400px;
- margin: 0 auto;
- padding-top: 25vh;
- }
- .code-copy-added {
- background-color: #282c34;
- color: white;
- padding: 25px 20px;
- margin: 10px 0;
- text-align: left;
- border-radius: 3px;
- position: relative;
- }
- .code-copy-added:hover .copy-btn {
- opacity: 1;
- }
- style>
CodeCopy.vue
- <template>
- <div class="copy-content">
-
- <div
- class="copy-btn code-data-copy"
- @click="copyMessage"
- data-clipboard-action="copy"
- :data-clipboard-text="code"
- >
- 复制
- div>
-
- div>
- template>
-
- <script>
- import Clipboard from 'clipboard' //复制插件
- export default {
- data () {
- return {
- code: null,
- // success: false
- }
- },
- methods: {
- copyMessage (value) {
- let _this = this
- // _this.success = false
- let clipboard = new Clipboard('.code-data-copy')
- clipboard.on('success', function (e) {
- _this.$message.success('复制成功')
- // _this.success = true
- // setTimeout(() => {
- // _this.success = false
- // }, 300)
- clipboard.destroy() // 销毁,避免多次点击重复出现
- })
- clipboard.on('error', function () {
- console.log('复制失败')
- })
- }
- }
- }
- script>
-
- <style lang="scss" scoped>
- .copy-content {
- height: 0;
- // position: absolute;
- // top: 0;
- // right: 0;
- }
-
- .icon {
- width: 0.8rem;
- height: 0.8rem;
- fill: white;
- }
- .copy-btn {
- user-select: none;
- opacity: 0;
- position: absolute;
- right: 5px;
- top: 5px;
- cursor: pointer;
- padding: 5px;
- border-radius: 3px;
- transition: 0.3s;
- // background: rgba(255, 255, 255, 0.2);
- background: #fff;
- &:active {
- // background: rgba(253, 253, 253, 0.575);
- background: rgba(253, 253, 253, 0.575);
- }
- }
- .copy-success-text {
- color: white;
- position: absolute;
- font-size: 12px;
- top: 8px;
- right: 2.5rem;
- font-weight: 200;
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen,
- Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
- animation: successCopy 0.5s ease both 1;
- }
- @keyframes successCopy {
- 70% {
- opacity: 1;
- transform: scale(1);
- }
- 100% {
- opacity: 0;
- transform: scale(0.5);
- }
- }
- style>