Vue2实现markdown语法支持

Vue2实现markdown语法支持,代码高亮,显示行号,复制功能

涉及组件:vue-markdownhighlight.jshighlight-line-numbersclipboard

完成功能:将数据以markdown格式渲染 ,代码部分高亮 ,代码显示行号 ,代码可一键复制

1.依赖安装
// 安装vue-markdown依赖
npm install vue-markdown
// 安装高亮
npm install highlight.js
// 安装代码行显示
npm install hightlight-line-numbers.js
// 安装复制组件
npm install clipboard --save 
2.highligh

①highlight-plugin.js插件

import Vue from 'vue';
import Hljs from 'highlight.js'
import 'highlight.js/styles/stackoverflow-dark.css' // 样式文件

let Highlight = {};
Highlight.install = function(Vue, options) {
    Vue.directive('highligh', function(el) {
        let blocks = el.querySelectorAll('pre code');
        blocks.forEach((block, index) => {
            /** 代码高亮 */
            Hljs.highlightBlock(block);
            /** 手动添加一个hljs类名,防止不支持的语言背景变空白 */
            block.classList.add('hljs');
        })
    })
}

export default Highlight;

②main.js

// 引入使代码行高亮的插件
import Highlight from "./plugins/highlight-plugin"
// 引入vue-markdown
import VueMarkdown from "vue-markdown"
import Vue from "vue";

// 将vue-markdown注册为全局组件
Vue.component("vue-markdown",  VueMarkdown)
Vue.use(Highlight);
3.使用指令

在需要支持markdown语法的组件中使用即可,文章以search.vue为例

其中source属性为md语法的内容,将内容传进组件会自动转换为html并显示在页面,此时已经实现页面支持md语法,且代码块高亮也支持,效果如下。接下来将实现代码行号显示语言显示复制代码

<template>
	<vue-markdown :source="item.content" v-highlight>
    </vue-markdown>
</template>
<script>
    
</script>

在这里插入图片描述

4.行号显示

highlight-plugin.js插件下将highlight-line-numbers引入,并新增一行代码将行号显示。

import Vue from 'vue';
import Hljs from 'highlight.js'
import 'highlight.js/styles/stackoverflow-dark.css' // 样式文件
import 'highlight-line-numbers'

let Highlight = {};
Highlight.install = function(Vue, options) {
    Vue.directive('highligh', function(el) {
        let blocks = el.querySelectorAll('pre code');
        blocks.forEach((block, index) => {
            /** 代码高亮 */
            Hljs.highlightBlock(block);
            /** 手动添加一个hljs类名,防止不支持的语言背景变空白 */
            block.classList.add('hljs');
            /** 显示行号 **/
            Hljs.lineNumbersBlock(block);
        })
    })
}

export default Highlight;

但是页面并没有出现对应的行号显示,且控制台显示highligh not...的错误,因为highlight-line-numbers默认自动执行,因此,需要对该代码进行修改。

  1. 将highlight-line-numbers.js里的代码全选复制

  2. 新建文件,修改如下

   function lineNumberInit(hljs, w, d) {
       // jshint multistr:true
   
      xxxx原代码内容
   
   export { lineNumberInit }
if (hljs) {
 hljs.initLineNumbersOnLoad = initLineNumbersOnLoad;
 hljs.lineNumbersBlock = lineNumbersBlock;
 hljs.lineNumbersValue = lineNumbersValue;

 addStyles();
} else {
 w.console.error("highlight.js not detected!");
}

  1. highlight-plugin.js文件下引入该文件,并修改代码
// highlight.js
import Vue from 'vue'
import Hljs from 'highlight.js'
import 'highlight.js/styles/stackoverflow-dark.css'
import { lineNumberInit } from "../utils/highlight-line-numbers.js";
lineNumberInit(Hljs, window, window.document);

let Highlight = {}
Highlight.install = function (Vue, options) {
    Vue.directive('highlight', function (el) {
        let blocks = el.querySelectorAll('pre code');
        blocks.forEach((block, index) => {
            /** 代码高亮 */
            Hljs.highlightBlock(block);
            /** 手动添加一个hljs类名,防止不支持的语言背景变空白 */
            block.classList.add('hljs');
            /** 从这开始是设置行号 */
            Hljs.lineNumbersBlock(block);
        })
    })
}
export default Highlight

此时,代码块成功实现行号显示。

5.copy

search.vue中引入clipboard实现复制功能。

要实现代码语言显示复制功能的前置条件,必须要有对应的元素进行展示。此处,选择操作DOM元素的方式在代码块元素pre之前创建对应的元素进行展示。

代码如下:

<template>
	<vue-markdown :source="item.content" v-highlight v-copy>
    </vue-markdown>
</template>
<script>
import Clipboard from "clipboard";
export default {
    created() {
        // 在 created 钩子函数中定义全局变量 clipboard
    	let clipboard = new Clipboard(".copy-btn");
    	clipboard.on("success", e => {
      		this.$message(messageCreate("success", "复制成功"));
      		e.clearSelection();
    	});
    	clipboard.on("error", e => {
      		this.$message(messageCreate("error", "复制失败"));
    	});
	},
      directives: {
          inserted(el) {
        	let blocks = el.querySelectorAll("pre");
        	blocks.forEach(block => {
          		let code = block.querySelector("code");
          		let div = document.createElement("div");
          		let span = document.createElement("span");
          		span.innerHTML = getLanguage(code.className);
          		div.appendChild(span);
          		div.classList.add("btn-copy");
          		let button = document.createElement("button");
          		button.setAttribute("data-clipboard-text", code.innerText);
          		button.innerText = "复制";
          		div.appendChild(button);
          		button.classList.add("copy-btn");
          		block.parentNode.insertBefore(div, block);
        });
      }
      }
}    
</script>
最终效果

此时,已经成功实现了代码的高亮、行号、语言、复制代码功能。
在这里插入图片描述

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值