学习链接

漂亮的代码语法高亮插件Prism.js简单使用文档
Prism官网

Prism高亮代码(html版)

官网下载js和css

官网下载地址>>

在这里插入图片描述

代码1

效果

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <!-- 引入prism.css -->
    <link rel="stylesheet" href="./prism/prism.css">
</head>

<body>
    <div style="width:500px;margin: 10px auto;">

        <!-- 一定要满足下面代码的dom结构,然后,再引入从prism官网下载的js -->
        <!-- 试了一下:将language-语言, 加在pre这个标签里面也是可以的; 将line-numbers加在code这个标签里也是可以的,都是一样的效果 -->
        <pre class="line-numbers">
            <code class="language-css">p { color: red }</code>
        </pre>

        <pre>
            <code class="language-java">
                package com.zzhua;

                import org.mybatis.spring.annotation.MapperScan;
                import org.springframework.boot.SpringApplication;
                import org.springframework.boot.autoconfigure.SpringBootApplication;

                @SpringBootApplication
                @MapperScan("com.zzhua.mapper")
                public class VueApp {
                    public static void main(String[] args) {
                        SpringApplication.run(VueApp.class);
                    }
                }

            </code>
        </pre>
    </div>
</body>

<!-- 引入jquery操作dom -->
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.4/jquery.js"></script>

<script>
    // 使用代码添加行号(这里是使用jquery给所有的 pre标签 加上 line-number 这个类名,也可以如上面自己手动加入这个类名),然后,再去引入prism.js,让prism生成行号相关的dom结构出来
    $('pre').each(function () {
        $(this).addClass('line-numbers');
    })
</script>

<!-- 让prism.js处理代码高亮 -->
<script src="./prism/prism.js"></script>

</html>

代码2

但通常使用这个插件的时候,是通过异步加载数据再渲染成html的,所以需要在加载完成之后,再高亮代码

效果

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <!-- 引入prism.css -->
    <link rel="stylesheet" href="./prism/prism.css">
</head>

<body>
    <div style="width:500px;margin: 10px auto;" id="div1">

        <!-- 一定要满足下面代码的dom结构,然后,再引入从prism官网下载的js -->
        <!-- 试了一下:将language-语言, 加在pre这个标签里面也是可以的; 将line-numbers加在code这个标签里也是可以的,都是一样的效果 -->
        <pre class="line-numbers">
            <code class="language-css">p { color: red }</code>
        </pre>

        <pre>
            <code class="language-java">
                package com.zzhua;

                import org.mybatis.spring.annotation.MapperScan;
                import org.springframework.boot.SpringApplication;
                import org.springframework.boot.autoconfigure.SpringBootApplication;

                @SpringBootApplication
                @MapperScan("com.zzhua.mapper")
                public class VueApp {
                    public static void main(String[] args) {
                        SpringApplication.run(VueApp.class);
                    }
                }

            </code>
        </pre>
    </div>
</body>

<!-- 引入jquery操作dom -->
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.4/jquery.js"></script>

<script>
    // 使用代码添加行号(这里是使用jquery给所有的 pre标签 加上 line-number 这个类名,也可以如上面自己手动加入这个类名),然后,再去引入prism.js,让prism生成行号相关的dom结构出来
    $('pre').each(function () {
        $(this).addClass('line-numbers');
    })
</script>

<!-- 让prism.js处理代码高亮 -->
<script src="./prism/prism.js"></script>

<!-- 让prism.js处理代码高亮 -->
<script>
    setTimeout(()=>{
        $('#div1').append($(`
	        <pre class="line-numbers">
	            <code class="language-java">
		            public class Result {
		
		                private Integer code;
		
		                private String msg;
		
		                private T data;
		            }
		        </code>
	        </pre>
        `))
        // 会全局注册一个Prism对象,里面有方法:highlight、highlightAll、highlightElement、highlightAllUnder等书方法
        console.log(Prism)
        
        // Prism.highlightAll(); // 也可以这样
        
		let blocks = document.querySelectorAll("pre code");
        blocks.forEach((block) => {
            Prism.highlightElement(block);
        });
    }, 2000)
</script>
</html>

Prism高亮代码(vue版)

Vue页面代码高亮展示之Prism语法高亮工具
Vue中使用Prism来显示代码高亮
babel-plugin-prismjs -> www.npmjs.com
Nuxt3中使用prismjs高亮代码

基础使用

在这里插入图片描述

已添加行号插件,未添加复制代码插件的dom示意图

在这里插入图片描述

添加行号 和 一键复制插件的dom示意图

在这里插入图片描述

安装prismjs

Prism官网上有这部分内容

npm i prismjs
vue组件中使用
  • 需要引入prismjs
  • 需要引入prismjs的样式
  • 需要引入对应的语言,它默认只引入了js、css、markup、clike这几种语言
  • 需要使用language-xxx的类名,来指定语言
  • 下面还引入了其它的插件的例子:行号插件 和 一键复制插件
<style lang="scss">

body {
    margin: 0;
}

/* 整个滚动条 */
::-webkit-scrollbar {
    width: 10px;
    height: 10px;
}

/* 滚动条上的滚动滑块,参考: 滚动条样式修改->https://blog.csdn.net/coder_jxd/article/details/124213962 */
::-webkit-scrollbar-thumb {
    background-color: #49b1f5;
    /* 关键代码 */
    background-image: -webkit-linear-gradient(45deg,
            rgba(255, 255, 255, 0.4) 25%,
            transparent 25%,
            transparent 50%,
            rgba(255, 255, 255, 0.4) 50%,
            rgba(255, 255, 255, 0.4) 75%,
            transparent 75%,
            transparent);
    border-radius: 32px;
}

/* 滚动条样式,参考: */
/* 滚动条轨道 */
::-webkit-scrollbar-track {
    background-color: #dbeffd;
    border-radius: 32px;
}





ul,
li {
    margin: 0;
    padding: 0;
    list-style: none;
}

.article {

    width: 800px;
    margin: 0 auto;
    margin-top: 50px;

    .article-content {
        padding: 15px;
        border-radius: 5px;
        box-shadow: 0 2px 8px 0 rgba(0, 0, 0, 0.16);
    }


}
</style>

<template>
    <div class="article ">

        <div id="div01"></div>

        <el-button @click="doTest">div01</el-button>

        <!-- 需要在pre或code上,使用language-xxx类名指定xxx语言,否则,prismjs是不会拆掉code标签里的代码内容的
             对于下面这3个已经预先写好的代码内容,在引入prismjs后,文档加载完后,前面2个就会自动拆掉的,第3个没有指定语言,因此不会拆 -->
        <pre id="pre01" class="language-java"><code class="line-numbers"  data-prismjs-copy="复制代码" data-prismjs-copy-success="复制成功" data-prismjs-copy-timeout="1000">
@SpringBootApplication
@MapperScan("com.zzhua.mapper")
public class VueApp {
    public static void main(String[] args) {
        SpringApplication.run(VueApp.class);
    }
}
        </code></pre>
        <pre id="pre02" class="line-numbers"><code class="language-java">
@SpringBootApplication
@MapperScan("com.zzhua.mapper")
public class VueApp {
    public static void main(String[] args) {
        SpringApplication.run(VueApp.class);
    }
}
        </code></pre>
        <pre id="pre03" class="line-numbers"><code>
@SpringBootApplication
@MapperScan("com.zzhua.mapper")
public class VueApp {
    public static void main(String[] args) {
        SpringApplication.run(VueApp.class);
    }
}
        </code></pre>

        


        <div ref="artcileContentRef" class="article-content" id="article-content" v-html="htmlContent"></div>
    </div>
</template>

<script>
import { getArticle } from '@/api/articleApi'

/* 引入prismjs */
import prismjs from 'prismjs'
/* 引入样式主题 */
import 'prismjs/themes/prism-okaidia.css'


/* 如果要支持高亮java语言的话,需要引入这个,其它的语言需要引入prism-{language}
   否则,无法处理java语言。 */
import 'prismjs/components/prism-java';  

/* 引入行号插件,对应的js和css都要引入, 然后在code或pre上添加line-numbers这个类名就行了 */
import 'prismjs/plugins/line-numbers/prism-line-numbers.js'
import 'prismjs/plugins/line-numbers/prism-line-numbers.css'

import 'prismjs/plugins/toolbar/prism-toolbar.js'
import 'prismjs/plugins/toolbar/prism-toolbar.css'
/* 在引入拷贝到剪贴板这个插件之前,要先引入上面这个prism-toolbar.js和prism-toolbar.css
   然后,代码的右上角在高亮操作之后,就会出现拷贝代码的按钮,不过是英文的,可以使用data-prismjs-copy等属性修改为中文 */
import 'prismjs/plugins/copy-to-clipboard/prism-copy-to-clipboard.js'

console.log(Prism);
console.log(Prism === prismjs); // true 说明它会全局注册一个Prism对象供我们使用
 
/* 输出:// ['manual', 'disableWorkerMessageHandler', 'util', 'languages', 'plugins', 'highlightAll', 'highlightAllUnder', 'highlightElement', 'highlight', 'tokenize', 'hooks', 'Token', 'filename'] */
console.log('Prism', Object.keys(Prism)); 

const code = `var data = 1;`;
const html = Prism.highlight(code, prismjs.languages.javascript, 'javascript'); // 它默认已经引入了css/javascript,不需要引入js语言
/* 输出:<span class="token keyword">var</span> data <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span> */
console.log(html);

const code2 = `SpringApplication.run(VueApp.class);`;
const html2 = Prism.highlight(code2, prismjs.languages.java, 'java'); // 如果未引入java语言,这里会报错:Error: The language "java" has no grammar.
/* 输出: <span class="token class-name">SpringApplication</span><span class="token punctuation">.</span><span class="token function">run</span><span class="token punctuation">(</span><span class="token class-name">VueApp</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">)</span><span class="token punctuation">;</span>*/
console.log(html2);




export default {
    name: 'ArticleView2',
    data() {
        return {
            htmlContent: '',
            content: '',
        }
    },
    created() {
        getArticle(this.$route.params.articleId).then(data => {
            this.htmlContent = data.htmlContent
            this.$nextTick(()=>{

                /* 给文章里的代码添加行号,否则只有前面写在html里的code才有行号 */
                let preBlocks = document.querySelectorAll('pre')
                preBlocks.forEach(preBlock => {
                    if(!preBlock.classList.contains('line-numbers')) {
                        preBlock.classList.add('line-numbers')
                    }
                })

                // 当渲染完成之后,高亮所有代码(注意,只有pre或code里带了language-xxx语言的才会处理)
                Prism.highlightAll()
            })
        })
    },
    mounted() {
        // 虽然在created里面已经发出请求了,这里获取的innerHTML是空的(不要被控制台的打印的this.$refs['artcileContentRef']迷惑了)
        // 因为上面getArticle是用的Promise,是异步的。所以不能在这里去做高亮的操作。应该在created里面发出请求并且得到响应后的$nextTick中去做高亮操作
        console.log('articleContentRef',this.$refs['artcileContentRef'],this.$refs['artcileContentRef'].innerHTML);
    },
    methods: {
        doTest() {
            let div01 = document.querySelector('#div01')
            div01.innerHTML = `<pre id="pre04" class="line-numbers language-java"><code>@SpringBootApplication
@MapperScan("com.zzhua.mapper")
public class VueApp {
    public static void main(String[] args) {
        SpringApplication.run(VueApp.class);
    }
}</code></pre>`
            // Prism.highlightElement(div01) // 不能传入div01
            // Prism.highlightElement(document.querySelector('#pre04')) // 不能传入pre,它会把code给删了,虽然代码内容拆了并且样式还在
            Prism.highlightElement(document.querySelector('#pre04 code'))

        }


    },
    components: {
    }
}
</script>

配合babel-plugin-prismjs使用

文章中的代码,并没有加上行号,是因为没有加上line-numbers这个类名,使用js加上类名就可以了。

在这里插入图片描述

安装prismjs
npm install prismjs
配置babel.config.js

在babel.config.js中添加如下插件,其它配置项,可以直接看prism这个包的源码里面找到对应的名字,写在这里就可以了。

module.exports = {
  presets: [
    '@vue/cli-plugin-babel/preset'
  ],
  "plugins": [
    ["prismjs", {
        "languages": ["javascript", "css", "markup","java", "sql","yml","properties"],
        "plugins": ["line-numbers","copy-to-clipboard",'previewers'],
        "theme": "okaidia",
        "css": true
    }]
  ]
}
main.js中引入prismjs
import Vue from 'vue'
import App from './App.vue'
import router from './router'

import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';

import 'prismjs' // 引入即可,它会注册一个Prism对象到window上面

Vue.config.productionTip = false

Vue.use(ElementUI);

new Vue({
  router,
  render: h => h(App)
}).$mount('#app')

vue组件中使用
<style lang="scss">

body {
    margin: 0;
}

/* 整个滚动条 */
::-webkit-scrollbar {
    width: 10px;
    height: 10px;
}

/* 滚动条上的滚动滑块,参考: 滚动条样式修改->https://blog.csdn.net/coder_jxd/article/details/124213962 */
::-webkit-scrollbar-thumb {
    background-color: #49b1f5;
    /* 关键代码 */
    background-image: -webkit-linear-gradient(45deg,
            rgba(255, 255, 255, 0.4) 25%,
            transparent 25%,
            transparent 50%,
            rgba(255, 255, 255, 0.4) 50%,
            rgba(255, 255, 255, 0.4) 75%,
            transparent 75%,
            transparent);
    border-radius: 32px;
}

/* 添加行号插件后,它默认把滚动条给覆盖了,所以将padding-left改成margin-left */
[class*=v-md-prism-] {
    margin-left: 72px !important;
    padding-left: 0 !important;
}

/* 滚动条样式,参考: */
/* 滚动条轨道 */
::-webkit-scrollbar-track {
    background-color: #dbeffd;
    border-radius: 32px;
}





ul,
li {
    margin: 0;
    padding: 0;
    list-style: none;
}

.article {

    width: 800px;
    margin: 0 auto;
    margin-top: 50px;

    .article-content {
        padding: 15px;
        border-radius: 5px;
        box-shadow: 0 2px 8px 0 rgba(0, 0, 0, 0.16);
    }


}
</style>

<template>
    <div class="article ">

        <div id="div01"></div>

        <el-button @click="doTest">div01</el-button>

        <pre id="pre01" class="language-java"><code class="line-numbers"  data-prismjs-copy="复制代码" data-prismjs-copy-success="复制成功" data-prismjs-copy-timeout="1000">
@SpringBootApplication
@MapperScan("com.zzhua.mapper")
public class VueApp {

}
        </code></pre>
        <pre id="pre02" class="line-numbers"><code class="language-java">
@SpringBootApplication
@MapperScan("com.zzhua.mapper")
public class VueApp {
    public static void main(String[] args) {
        SpringApplication.run(VueApp.class);
    }
}
        </code></pre>
        <pre id="pre03" class="line-numbers"><code>
@SpringBootApplication
@MapperScan("com.zzhua.mapper")
public class VueApp {
    public static void main(String[] args) {
        SpringApplication.run(VueApp.class);
    }
}
        </code></pre>

<pre class="language-css"><code>div {
	/* Only the previewer for color and time are enabled */
	color: red;
	transition-duration: 1s;
	/* The previewer for angles is not enabled. */
	transform: rotate(10deg);
}</code></pre>

        


        <div ref="artcileContentRef" class="article-content" id="article-content" v-html="htmlContent"></div>
    </div>
</template>

<script>
import { getArticle } from '@/api/articleApi'

export default {
    name: 'ArticleView2',
    data() {
        return {
            htmlContent: '',
            content: '',
        }
    },
    created() {
        console.log(Prism);
        getArticle(this.$route.params.articleId).then(data => {
            this.htmlContent = data.htmlContent
            this.$nextTick(()=>{

                Prism.highlightAll()
                
            })
        })
    },
    mounted() {
    },
    methods: {
        doTest() {
            let div01 = document.querySelector('#div01')
            div01.innerHTML = `<pre id="pre04" class="line-numbers language-java"><code>@SpringBootApplication
@MapperScan("com.zzhua.mapper")
public class VueApp {
    public static void main(String[] args) {
        SpringApplication.run(VueApp.class);
    }
}</code></pre>`
            // Prism.highlightElement(document.querySelector('#pre04')) // 使用这个方法代码有高亮,但没有加行号
            Prism.highlightAll() // 使用这个方法,有高亮,有行号
        }


    },
    components: {
    }
}
</script>


highlight.js高亮代码(html版本)

highlight.js -> www.npmjs.com
JS库之Highlight.js高亮代码
程序员必备的代码高亮插件 Highlight.JS

highlight.js官网
1. 发现highlight.js官网下面的原来可以直接点击选择语言和主题,实时预览效果的阿
2. 在线选字体,使用在线链接:谷歌在线字体

也可以试试:highlight.js中文网,也可以在线预览效果的

代码

效果

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.4/jquery.js"></script>
    <style>
        .box {
            width: 500px;
            margin: 10px auto;
        }

		pre code.hljs {
            display: block;
            padding: 0;
            overflow-x: auto;
            font-family: 'Consolas', 'Courier New', monospace;
            font-weight: 400;
        }
    </style>
    <!-- 可以直接引入cdn -->
    <!-- <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/styles/atom-one-dark.min.css">
    <script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/highlight.min.js"></script> -->

    <!-- 可以在官网下载 -->
    <script src="./hljs/highlight.min.js"></script><!-- 导入这个highlight.min.js,不要导入highlight.js,不然还要注册语言,有点麻烦 -->
    <link rel="stylesheet" href="./hljs/styles/atom-one-dark.min.css">
    <script>
        window.onload = function () {
        	// 它会在全局注册一个hljs,里面有highlightAll、highlightElement、highlightBlock、highlight等方法
            console.log(hljs);
            hljs.highlightAll()

            html = hljs.highlight('<h1>Hello World!</h1>', { language: 'xml' }).value
            console.log(html); // 输出:<span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Hello World!<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>

            setTimeout(() => {
                $('#div1').append($(`<pre><code>
                                        public class Result {

                                            private Integer code;

                                            private String msg;

                                            private T data;
                                        }
                                    </code>
                                </pre>`))

                // hljs.highlightAll() // 也可以这样

                let blocks = document.querySelectorAll("pre code");
                document.querySelectorAll('pre code').forEach((el) => {
                    hljs.highlightElement(el);
                });
            }, 1000)
        }
    </script>
</head>

<body>
    <div class="box">
        <pre>
            <code class="language-java">
                package com.zzhua;
    
                import org.mybatis.spring.annotation.MapperScan;
                import org.springframework.boot.SpringApplication;
                import org.springframework.boot.autoconfigure.SpringBootApplication;
    
                @SpringBootApplication
                @MapperScan("com.zzhua.mapper")
                public class VueApp {
                    public static void main(String[] args) {
                        SpringApplication.run(VueApp.class);
                    }
                }
    
            </code>
        </pre>
        <div id="div1"></div>
    </div>
</body>

</html>

原生js实现手动添加行号

参考:B站视频->给你的网页代码框添加一个行号吧!!!

代码

主要的实现思路:使用highlight.js给pre code添加高亮后,获取code标签下的所有html,在这个html里面,行与行之间有换行符的存在,按换行符分割,创建li,把行号添加进去,塞到ul里面,然后,使用定位把行号定到左边去。滚动条的样式是固定代码。

以下代码的资源代码都是在线的,可以随时复制粘贴测试使用,比较方便,这个字体也是在线的,可能要翻墙才能用吧

效果

在这里插入图片描述
在这里插入图片描述

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>

    <style>
        /* 整个滚动条 */
        ::-webkit-scrollbar {
            width: 10px;
            height: 10px;
        }

        /* 滚动条上的滚动滑块,参考: 滚动条样式修改->https://blog.csdn.net/coder_jxd/article/details/124213962 */
        ::-webkit-scrollbar-thumb {
            background-color: #49b1f5;
            /* 关键代码 */
            background-image: -webkit-linear-gradient(45deg,
                    rgba(255, 255, 255, 0.4) 25%,
                    transparent 25%,
                    transparent 50%,
                    rgba(255, 255, 255, 0.4) 50%,
                    rgba(255, 255, 255, 0.4) 75%,
                    transparent 75%,
                    transparent);
            border-radius: 32px;
        }

        /* 添加行号插件后,它默认把滚动条给覆盖了,所以将padding-left改成margin-left */
        [class*=v-md-prism-] {
            margin-left: 72px !important;
            padding-left: 0 !important;
        }

        /* 滚动条样式,参考: */
        /* 滚动条轨道 */
        ::-webkit-scrollbar-track {
            background-color: #dbeffd;
            border-radius: 32px;
        }

        * {
            margin: 0;
            padding: 0;
            font-size: 18px;
            font-family: 'Dancing Script';
            list-style: none;
        }

        body {
            height: 100vh;
            padding-top: 10px;
        }

        #code-box {
            width: 500px;
            border-radius: 6px;
            overflow: hidden;
            margin: 0 auto;

            position: relative;
        }

        #code {
            padding-left: 61px;
            background-color: #282c34;
        }

        #number-line {
            position: absolute;
            color: #cdcdcd;
            padding: 0px 15px 18px 10px;
            text-align: right;
            width: 30px;
            margin-top: 18px;
            font-size: 14px;
            font-family: 'Courier New', Courier, monospace;
            border-right: 1px solid #7d7d7d;
        }
    </style>

    <link rel="stylesheet" href="//unpkg.com/@highlightjs/cdn-assets@11.7.0/styles/atom-one-dark.min.css">
    <script src="//unpkg.com/@highlightjs/cdn-assets@11.7.0/highlight.min.js"></script>

    <script>
        window.onload = () => {
            hljs.highlightAll()

			/* &lt;<span class="hljs-selector-tag">span</span>&gt;Hello World!&lt;/<span class="hljs-selector-tag">span</span>&gt; */
            console.log(hljs.highlightAuto('<span>Hello World!</span>').value); 
            /* <span class="hljs-tag">&lt;<span class="hljs-name">span</span>&gt;</span>Hello World!<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span> */
            console.log(hljs.highlight('<span>Hello World!</span>', {language: 'xml'}).value); 

            let EL_NUMBER_LINE = document.getElementById('number-line')

			/*
			打印如下:
			<span class="hljs-variable">@SpringBootApplication</span>
			<span class="hljs-variable">@MapperScan</span>(<span class="hljs-string">"com.zzhua.mapper"</span>)
			public class VueApp {
			    <span class="hljs-selector-tag">public</span> <span class="hljs-selector-tag">static</span> <span class="hljs-selector-tag">void</span> <span class="hljs-selector-tag">main</span>(String[] args) {
			        <span class="hljs-selector-tag">SpringApplication</span><span class="hljs-selector-class">.run</span>(VueApp.class); <span class="hljs-selector-tag">SpringApplication</span><span class="hljs-selector-class">.run</span>(VueApp.class);
			    }
			}
			*/
            console.log(document.getElementById('code').childNodes[0].innerHTML);

            let LINE = document.getElementById('code').childNodes[0].innerHTML.split('\n').length
            console.log(LINE);

            for (let i = 1; i <= LINE; i++) {
                let li = document.createElement('li')
                let lineNum = document.createTextNode(i)
                li.appendChild(lineNum)
                EL_NUMBER_LINE.appendChild(li)
            }
        }
    </script>
</head>

<body>
    <div id="code-box">
        <ul id="number-line"></ul>
        <pre id="code"><code>@SpringBootApplication
@MapperScan("com.zzhua.mapper")
public class VueApp {
    public static void main(String[] args) {
        SpringApplication.run(VueApp.class); SpringApplication.run(VueApp.class);
    }
}</code></pre>
    </div>
</body>

</html>

highlight.js高亮代码(vue版)

效果

  • 原文内容是通过WangEditor编辑保存的,可以参考:WangEdtior富文本编辑器
  • 目录用的tocbot,具体使用可参考:tocbot生成文章目录
  • 使用原生js手动添加了行号,修改了滚动条样式
  • 实现代码高亮,注意实现代码高亮其实就是把code标签里的代码让highlight.js处理后,然后使用highlight.js提供的主题样式加花里胡哨的颜色。

在这里插入图片描述

代码

安装highlight.js
npm install highlight.js
vue组件中引入highlight.js 和 主题样式
import hljs from 'highlight.js';
import 'highlight.js/styles/atom-one-dark.css'
ArticleView.vue
<style lang="scss">
@import 'tocbot/src/scss/tocbot';
@import url('https://fonts.font.im/css?family=Roboto');

/* 整个滚动条 */
::-webkit-scrollbar {
    width: 10px;
    height: 10px;
}

/* 滚动条上的滚动滑块,参考: 滚动条样式修改->https://blog.csdn.net/coder_jxd/article/details/124213962 */
::-webkit-scrollbar-thumb {
    background-color: #49b1f5;
    /* 关键代码 */
    background-image: -webkit-linear-gradient(45deg,
            rgba(255, 255, 255, 0.4) 25%,
            transparent 25%,
            transparent 50%,
            rgba(255, 255, 255, 0.4) 50%,
            rgba(255, 255, 255, 0.4) 75%,
            transparent 75%,
            transparent);
    border-radius: 32px;
}

/* 添加行号插件后,它默认把滚动条给覆盖了,所以将padding-left改成margin-left */
[class*=v-md-prism-] {
    margin-left: 72px !important;
    padding-left: 0 !important;
}

/* 滚动条样式,参考: */
/* 滚动条轨道 */
::-webkit-scrollbar-track {
    background-color: #dbeffd;
    border-radius: 32px;
}

.article {
    width: 600px;
    margin: 10px auto;

    .article-content {
        width: 725px;
        padding: 15px;
        // border: 1px solid red;
        border-radius: 5px;
        box-shadow: 0 2px 8px 0 rgba(0, 0, 0, 0.16);
    }

    #toc-content {
        position: fixed;
        top: 20px;
        right: 50px;
    }
}


/* 行号相关样式 */
pre {
    background-color: #282c34;
    border-radius: 6px;
    position: relative;

    .line-numbers {
        position: absolute;
        color: #e0e0e0;
        font-size: 16px;
        margin: 16px 0;
        padding-right: 10px;
        width: 30px;
        text-align: right;
        font-family: 'Roboto', sans-serif;
        border-right: 1px solid #c5c5c5;
    }
}

code {
    font-family: 'Roboto', sans-serif;
    border-radius: 6px;

    padding-left: 0 !important;
    margin-left: 3em !important;


}

ul,
li {
    margin: 0;
    padding: 0;
    list-style: none;
}
</style>

<template>
    <div class="article">
        <!-- <div style="height: 500px;"> </div> -->
        <div class="article-content" id="article-content" v-html="htmlContent"></div>
        <div id="toc-content"></div>
    </div>
</template>

<script>
import { getArticle } from '@/api/articleApi'

// 引入highlight.js和主题样式
import hljs from 'highlight.js';
import 'highlight.js/styles/atom-one-dark.css'

console.log(hljs);

import tocbot from 'tocbot'
console.log('tocbot', tocbot);

export default {
    name: 'Article',
    data() {
        return {
            htmlContent: ''
        }
    },
    created() {
        getArticle(this.$route.params.articleId).then(data => {
            this.htmlContent = data.htmlContent
            this.$nextTick(() => {
                // console.log('$nextTick...');
                let articleContent = document.querySelector('#article-content')
                let headingTag = ['h1', 'h2', 'h3']
                let children = Array.from(articleContent.children)
                for (let i = 0; i < children.length; i++) {
                    const e = children[i];
                    e.id = `h-${i}`
                }

                hljs.highlightAll()

                let codes = document.querySelectorAll('code')

                console.log(codes);
                for (let i = 0; i < codes.length; i++) {

                    const codeBlock = codes[i];
                    // console.log(codeBlock.innerHTML);
                    let lineTotal = codeBlock.innerHTML.split('\n').length
                    let ul = document.createElement('ul')
                    ul.classList.add('line-numbers')
                    for (let i = 1; i <= lineTotal; i++) {
                        let li = document.createElement('li')
                        let lineNum = document.createTextNode(i)
                        li.appendChild(lineNum)
                        ul.appendChild(li)
                    }
                    codeBlock.parentNode.prepend(ul)
                }


                tocbot.init({
                    // Where to render the table of contents.
                    tocSelector: '#toc-content',
                    // Where to grab the headings to build the table of contents.
                    contentSelector: '#article-content',
                    // Which headings to grab inside of the contentSelector element.
                    headingSelector: 'h1, h2, h3, h4, h5, h6',
                    // For headings inside relative or absolute positioned containers within content.
                    hasInnerContainers: true,
                });
            })
        })
    },
    mounted() {
        // console.log('mounted');

    },
    components: {
    }
}
</script>

Clipboard.js实现一键复制

思路:先把要复制的内容用textarea装起来,并用id标识它,然后这个textarea绝对定位,left放很远,top放很远。然后使用一个按钮,按钮的目标id指向这个标识,然后使用clipboard的复制功能即可,可以参考:markdown-it基本使用

clipboardjs官网

基础使用

在这里插入图片描述
JavaScript | 文本复制工具clipboard.js的使用详解(使用clipboard复制ajax请求的数据)

<!-- 该代码可直接创建HTML文件运行 -->
<html lang="zh-CN">
  <head>
    <meta charset="UTF-8" />
    <title>target-input</title>
    <meta name="viewport" content="width=device-width, initial-scale=1" />
  </head>
  <body>
    <!-- 1. 定义一些标记 -->
    <!-- 2. 设置按钮 -->
      
    <!-- 示例1:复制input元素的value值 -->  
    <input id="foo" type="text" value="这是input元素的value值" />
    <button class="btn" data-clipboard-action="copy" data-clipboard-target="#foo">点击复制</button> 
     
    <br/>
    <hr/>

    <!-- 示例2:剪切textarea元素的值 -->
    <textarea id="bar">这里的文本可被复制或者剪切</textarea>
    <button class="btn" data-clipboard-action="cut" data-clipboard-target="#bar">点击剪切文字</button>
      
    <br/>
    <hr/>

    <!-- 示例3:复制div元素的值 -->
    <div>这是div元素里的文字</div>
    <button class="btn" data-clipboard-action="copy" data-clipboard-target="div">复制来自div的文字</button>

    <br/>
    <hr/>

    <!-- 示例4:复制button自己设置的值 -->
    <button class="btn" data-clipboard-text="这里的文字将被复制">复制自己的文字</button>


    <!-- 3. 引入库文件 -->
    <!--  <script src="../dist/clipboard.min.js"></script> -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.6/clipboard.min.js"></script>

    <script>
      //4. 实例化clipboard
      var clipboard = new ClipboardJS('.btn');

      //5. 复制成功的响应事件【按F12控制台可见】
      clipboard.on('success', function (e) {
        console.log(e);
        //打印动作信息(copy或者cut)
        console.info('Action:', e.action);
        //打印复制的文本
        console.info('Text:', e.text);
        //打印trigger
        console.info('Trigger:', e.trigger);
      });

      //6. 复制失败的响应事件
      clipboard.on('error', function (e) {
        console.log(e);          
        console.error('Action:', e.action);
        console.error('Trigger:', e.trigger);
      });
    </script>
  </body>
</html>

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐