在 React 中使用 highlight.js 和 Clipboard.js 实现代码块和复制功能

news/2024/11/30 14:41:05/

参考链接:https://blog.csdn.net/huangjuan0229/article/details/130319050

在前端开发中,代码块高亮和复制功能是十分常见的需求。而在 React 中,常用的代码高亮库是 highlight.js,常用的复制库是 Clipboard.js。本篇文章将介绍如何在 React 中使用这两个库,实现代码高亮和复制功能。

安装 highlight.js 和 Clipboard.js

首先,在我们的 React 项目中安装 highlight.js 和 Clipboard.js:

npm install highlight.js clipboard --save

注意:
这里的库是highlight.js,不是highlight,博主就因为npm了highlight踩了一些坑,小伙伴们注意一下

安装完成后,我们就可以在 React 中使用这两个库了。
可以在package.json中查看
在这里插入图片描述

配置 highlight.js 支持的语言

highlight.js 支持很多种语言的代码高亮,我们需要配置支持的语言。在本例中,我们只演示部分语言的高亮,可根据自己的需要进行配置。我们创建一个 src/highlight.js 文件:

import hljs from 'highlight.js/lib/core';
// 导入需要的语言高亮
import javascript from 'highlight.js/lib/languages/javascript';
import java from 'highlight.js/lib/languages/java';
import csharp from 'highlight.js/lib/languages/csharp';
import php from 'highlight.js/lib/languages/php';
import python from 'highlight.js/lib/languages/python';
import objectivec from 'highlight.js/lib/languages/objectivec';
import bash from 'highlight.js/lib/languages/bash';hljs.registerLanguage('javascript', javascript);
hljs.registerLanguage('java', java);
hljs.registerLanguage('csharp', csharp);
hljs.registerLanguage('php', php);
hljs.registerLanguage('python', python);
hljs.registerLanguage('objectivec', objectivec);
hljs.registerLanguage('bash', bash);export default hljs;

在这个文件中,我们导入了需要使用的语言高亮,并注册到了 highlight.js 中,最后导出了 hljs 对象。这样,我们就可以在 React 中方便地使用 highlight.js 了。

创建 CodeBlock 组件

我们创建一个 src/components/CodeBlock/index.js 文件,实现 CodeBlock 组件:

import React, { useEffect, useRef, useState } from 'react';
import hljs from '../../highlight';
import Clipboard from 'clipboard';import 'highlight.js/styles/dark.css';export default function CodeBlock({ language, code }) {const preRef = useRef(null);const [copied, setCopied] = useState(false);useEffect(() => {if (preRef.current) {hljs.highlightBlock(preRef.current);// 创建 clipboard 实例并保存到变量中const clipboard = new Clipboard(`#${language}copy_btn`, {text: () => code,});// 监听复制成功事件clipboard.on('success', () => {setCopied(true);setTimeout(() => setCopied(false), 2000);});// 销毁 clipboard 实例return () => {clipboard.destroy();};}}, [code]);return (<div className="code-block" style={{ position: 'relative', marginTop: 8 }}><pre><code id={language} ref={preRef} className={language}>{code}</code></pre><button id={`${language}copy_btn`} style={{ position: 'absolute', top: 4, right: 4, lineHeight: '14px' }} className="code-block__button" data-clipboard-target={`#${language}`} disabled={!preRef.current}>{copied ? '已复制' : '复制'}</button></div>);
}

在这个组件中,我们使用了 useRefuseEffect 钩子,分别保存了代码块的 DOM 对象和复制按钮的 Clipboard 对象。在 useEffect 中,我们使用 highlight.js 对代码块进行了高亮,并创建了 Clipboard 实例,监听了复制成功事件。当点击复制按钮后,会将代码块的内容复制到剪贴板中,并在按钮上显示“已复制”,2 秒后消失。最后,我们将代码块和复制按钮显示在了页面上。

使用 CodeBlock 组件

import React from 'react';
import CodeBlock from '@/components/CodeBlock';export default function BlogPost() {const code = `import React from 'react';
import CodeBlock from '@/components/CodeBlock';export default function BlogPost() {const code = '111';return (<div><CodeBlock language="javascript" code={code} /></div>);
}`;return (<div><CodeBlock language="javascript" code={code} /></div>);
}

效果展示

在这里插入图片描述


http://www.ppmy.cn/news/71954.html

相关文章

Qt魔法书:打造自定义鼠标键盘脚本

Qt魔法书&#xff1a;打造自定义鼠标键盘脚本 一、引言&#xff08;Introduction&#xff09;1.1 脚本的重要性&#xff08;Importance of Scripts&#xff09;1.2 Qt在脚本制作中的优势&#xff08;Advantages of Qt in Script Making&#xff09;1.3 文章目标与结构概述&…

Java基础(43)File类(文件操作类)详解

在Java中&#xff0c;File 类是 java.io 包中唯一代表磁盘文件本身的对象&#xff0c;也就是说&#xff0c;如果希望在程序中操作文件和目录&#xff0c;则都可以通过 File 类来完成。File 类定义了一些方法来操作文件&#xff0c;如新建、删除、重命名文件和目录等。 File 类…

《永恒之塔sf私服》“龙战前传”里的更高挑战-

关于这个新版本的各种更新内容已经屡见不新&#xff0c;无论是最新关注的玩家&#xff0c;抑或是一直坚守在永恒之塔阵地的老玩家们&#xff0c;相信已经对各种感兴趣的更新倒背如流。这里就不再重复。 每一款MMO游戏升级&#xff0c;伴随着玩家技术和战术的长进&#xff0c;游…

Shell脚本的特殊变量和特殊符号应用

记录&#xff1a;428 场景&#xff1a;Shell脚本中常用特殊符号&#xff0c;&#xff0c;$&#xff0c;${}&#xff0c;$0&#xff0c;$n&#xff0c;$#&#xff0c;$*&#xff0c;$&#xff0c;$?&#xff0c;$$&#xff0c;(( ))&#xff0c;[[ ]]&#xff0c;$[]&#xff…

防火墙NAT策略中各项之间以及策略与策略之间的关系

实验结论 将实验结论写在前面方便大家直接查看 1、NAT策略中rule与rule之间的关系为“或”的关系&#xff0c;即多个rule存在时&#xff0c;流量只需要匹配其中一个rule即可&#xff0c;流量会按照匹配的rule规则进行流量转发。&#xff08;华为华三的防火墙rule是没有ID的&a…

【学习笔记】Rider调试unity【 联调、断点调试等】(决定弃用vscode了)

目录 一 弃用vscode原委二 Rider调试Unity2.1 启动调试2.2 pausepoint 暂停点2.2.1 使用pausepoint2.2.2 pausepoint&#xfeff;与breakpoint的区别 2.3 不同run configuration区别 三 Rider编辑3.1 补充 四 总结 转载请注明出处&#xff1a;&#x1f517;https://blog.csdn.n…

22届硕士,去年秋招拿了字节跳动offer,有一说一,不是很难进

自从抖音短视频APP火了之后&#xff0c;起公司字节跳动也逐渐向着大厂靠拢&#xff0c;相信大家都已经对这家公司很熟悉了&#xff0c;尤其是近几年来&#xff0c;对它的认识也在不断刷新&#xff0c;它惊人的发展速度确实让行业内人刮目相看&#xff0c;如今很多年轻人也想要挤…

SpringBoot——配置文件的分类

简单介绍&#xff1a; 在之前我们写配置文件的时候&#xff0c;我们直接在项目中的resources下面编写的配置文件&#xff0c;其实除了在这个路径下编写配置文件&#xff0c;还可以在其他的地方编写配置文件&#xff0c;并且不同位置的配置文件在启动的时候的优先级也是不一样的…