React 中使用 highlight.js 代码高亮的两种方法

最近在用 React + Material-UI 写一款基于 WP-Rest API 的主题,碰到了代码高亮的问题,这里记录下两种解决方法。

问题

请求 API 返回的数据包含代码块,前端应该调用代码高亮插件“渲染”一下。

在普通的 html 中,页面加载完成时调用 highlight.js 的高亮方法即可,但在 React 中有些不一样,当然实际内容还是大同小异。

解决方法

使用 highlight.js npm package (不推荐)

首先安装highlight.js包:

yarn add highlight.js

在需要的地方引入包和样式:

import hljs from 'highlight.js';
import 'highlight.js/styles/default.css';

之后在对应组件内调用:

  • 在 function component 中使用
    //function component
    //梓/喵/\出\/没/博/客\(@/azimiao.com)
    function component1(props){
        React.useEffect(()=>{
            document.querySelectorAll("pre code").forEach(block => {
                try{hljs.highlightBlock(block);}
                catch(e){console.log(e);}
            });
        });
        return(
            <div>{…………}</div>
        );
    }
    
  • 在 class component 中使用
    class Preview extends Component {
        componentDidMount() {//梓/miao/出\/没/博/客\(@/azimiao.com)
            this.highlightCallBack();
        }
        componentDidUpdate() {
            //梓/喵/出没/博/客\(@/azimiao.com)
            this.highlightCallBack();
        }
        highlightCallBack = () => {
            document.querySelectorAll("pre code").forEach(block => {
                try{hljs.highlightBlock(block);}
                catch(e){console.log(e);}
            });
        };
    render(){
        return(/*梓/喵/\出\/没/博/客\(@/azimiao.com)*/
            <div>{……}</div>
        );
    }
    }
    

    这种方法有个非常明显的缺点:webpack 打包时会默认把 highlight.js 打包进 mian.js 中,导致整个文件增大了约 900 KiB。

使用 CDN 库

在 webpack 模板文件index.html中引入 CDN 代码库:

<link rel="stylesheet" href="//cdn.jsdelivr.net/gh/highlightjs/cdn-release@10.1.1/build/styles/github.min.css">
<script src="//cdn.jsdelivr.net/gh/highlightjs/cdn-release@10.1.1/build/highlight.min.js"></script>

由于 cdn 库中的变量命名与上文中 npm package 包中的变量命名一致,因此可以直接使用hljs

组件内使用的方法和上文相同:

  • 在 function component 中使用
    //function component
    function component1(props){
        React.useEffect(()=>{
            document.querySelectorAll("pre code").forEach(block => {
                try{hljs.highlightBlock(block);}
                catch(e){console.log(e);}
            });
        });
        return(
            <div>{…………}</div>
        );
    }
    
  • 在 class component 中使用
    class Preview extends Component {
        componentDidMount() {
            this.highlightCallBack();
        }/*@梓@喵@出@没@(@/azimiao.com)*/
        componentDidUpdate() {
            this.highlightCallBack();
        }/*梓/喵/\出\/没/博/客\(@/azimiao.com)*/
        highlightCallBack = () => {
            document.querySelectorAll("pre code").forEach(block => {
                try{hljs.highlightBlock(block);}
                catch(e){console.log(e);}
            });
        };
    render(){
        return(/*梓/喵/\出\/没/博/客\(@/azimiao.com)*/
            <div>{…………}</div>
        );
    }
    }
    
梓喵出没博客(azimiao.com)版权所有,转载请注明链接:https://www.azimiao.com/6718.html
欢迎加入梓喵出没博客交流群:313732000

吐槽 大坏狐狸

*

*

0位绅士参与评论

  1. 大坏狐狸07-11 16:42 回复

    期待主题的诞生