前端語法高亮插件Prism.js使用詳細(xì)教程
介紹
最近項(xiàng)目有代碼高亮的需求,這邊是選用 Prism.js 來進(jìn)行代碼高亮。
Prism 是一款輕量級、可擴(kuò)展的語法高亮器,根據(jù)現(xiàn)代 Web 標(biāo)準(zhǔn)構(gòu)建,應(yīng)用廣泛。
官網(wǎng):https://prismjs.com/
文檔:https://prismjs.com/docs/index.html
示例

<!DOCTYPE html>
<html>
<head>
<!-- 可以通過 CDN 的方式導(dǎo)入 -->
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Prism Test</title>
<link rel="external nofollow" rel="external nofollow" rel="stylesheet" />
</head>
<body>
<pre class="line-numbers">
<code class="language-cpp">
#include <iostream>
using namespace std;
struct ListNode {
int val;
ListNode *next;
ListNode() : val(0), next(nullptr) {}
ListNode(int x) : val(x), next(nullptr) {}
ListNode(int x, ListNode *next) : val(x), next(next) {}
};
</code>
</pre>
<script src="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/components/prism-core.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/plugins/autoloader/prism-autoloader.min.js"></script>
<script
src="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/plugins/normalize-whitespace/prism-normalize-whitespace.min.js"
integrity="sha256-ronWqXsvaeyrdiX7YJfdYj0S5NbeMA5ilQQTrK25Jno="
crossorigin="anonymous"
></script>
</body>
</html>
主題
Prism.js 支持多種主題

插件
Prism.js 有多種插件可以使用,這里介紹幾個常用的插件。

1、show-language
在代碼塊中顯示代碼塊對應(yīng)語言的名稱
Show Language ▲ Prism plugins:https://prismjs.com/plugins/show-language

<pre>
<code class="language-js">
function curry(func) {
return function curried(...args) {
if (args.length >= func.length) {
return func.apply(this, args);
} else {
return function(...args2) {
return curried.apply(this, args.concat(args2));
}
}
};
}
</code>
</pre>2、line-numbers
在代碼塊中顯示行號
Line Numbers ▲ Prism plugins:https://prismjs.com/plugins/line-numbers/

<pre class="line-numbers">
<code class="language-js">
function curry(func) {
return function curried(...args) {
if (args.length >= func.length) {
return func.apply(this, args);
} else {
return function(...args2) {
return curried.apply(this, args.concat(args2));
}
}
};
}
</code>
</pre>通過添加 "line-numbers" class 來為代碼塊(<pre><code>)添加行號。
如果將 "line-numbers" class 添加到 <body> 中,則為所有代碼塊(<pre><code>)添加行號。
此外,我們可以使用 "no-line-numbers" class 來移除行號。
3、normalize-whitespace
標(biāo)準(zhǔn)化代碼塊中的空白字符Normalize Whitespace ▲ Prism plugins:https://prismjs.com/plugins/normalize-whitespace/
默認(rèn)情況下,該插件會裁剪每個代碼塊的所有前端和尾部空白字符,并移除每行上多余的縮進(jìn)和尾部空白字符。
可以通過添加 "no-whitespace-normalization" class 來阻止該插件生效。
示例代碼
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Prism Test</title>
<link href="prism.css" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="stylesheet" />
</head>
<body>
<pre>
<code class="language-js">
function curry(func) {
return function curried(...args) {
if (args.length >= func.length) {
return func.apply(this, args);
} else {
return function(...args2) {
return curried.apply(this, args.concat(args2));
}
}
};
}
</code>
</pre>
<script src="prism.js"></script>
</body>
</html>
不使用 normalize-whitespace 插件情況

使用 normalize-whitespace 插件情況
可以看到在使用 normalize-whitespace 插件情況下,代碼塊前端的空白字符被移除,更為美觀。
4、unescaped-markup
編寫標(biāo)記語言而無需轉(zhuǎn)義任何內(nèi)容
Unescaped markup ▲ Prism plugins:https://prismjs.com/plugins/unescaped-markup/

可以使用 <script type="text/plain" class="language-markup"> 方式
<script type="text/plain" class="language-markup"> <html></html> <p>Example</p> <div><button>Hello</button></div> </script>
也可以使用 <pre><code class="language-markup"><!-- --></code></pre> 方式
<pre>
<code class="language-markup"><!--
<html></html>
<p>Example</p>
<div><button>Hello</button></div>
--></code>
</pre>5、copy-to-clipboard
添加一個按鈕,可以在單擊時將代碼塊內(nèi)容復(fù)制到剪貼板
Copy to Clipboard ▲ Prism plugins:https://prismjs.com/plugins/copy-to-clipboard/默認(rèn)情況下,插件以英語顯示消息,并設(shè)置 5 秒的間隔復(fù)制時間。
可以使用以下屬性來覆蓋默認(rèn)設(shè)置:
- data-prismjs-copy — 默認(rèn)情況下復(fù)制按鈕顯示的文字
- data-prismjs-copy-error — 復(fù)制失敗時顯示的信息
- data-prismjs-copy-success — 復(fù)制成功時顯示的信息
- data-prismjs-copy-timeout — 兩次復(fù)制允許的間隔時間

<pre>
<code class="language-js"
data-prismjs-copy="復(fù)制"
data-prismjs-copy-error="復(fù)制失敗"
data-prismjs-copy-success="復(fù)制成功"
>
let range = new Range();
range.setStart(p1.firstChild, 2);
range.setEndAfter(p2.firstChild);
document.getSelection().addRange(range);
</code>
</pre>6、show-invisibles
顯示隱藏字符,例如制表符和換行符
Show Invisibles ▲ Prism plugins:https://prismjs.com/plugins/show-invisibles/

使用
1、直接下載
在下載界面選擇需要的語言和插件,下載 js 和 css, 然后導(dǎo)入使用
Download ▲ Prism:https://prismjs.com/download.html#themes=prism-tomorrow&languages=markup+css+clike+javascript

<!DOCTYPE html>
<html>
<head>
...
<link href="prism.css" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="stylesheet" />
</head>
<body>
...
<script src="prism.js"></script>
</body>
</html>
2、CDN 方式
可以使用 cdnjs、jsDelivr 和 UNPKG 等 cdn 導(dǎo)入 PrismJS

<!DOCTYPE html>
<html>
<head>
<!-- 通過 CDN 方式導(dǎo)入 -->
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Prism Test</title>
<link rel="external nofollow" rel="external nofollow" rel="stylesheet" />
</head>
<body>
<pre class="line-numbers">
<code class="language-cpp">
#include <iostream>
using namespace std;
struct ListNode {
int val;
ListNode *next;
ListNode() : val(0), next(nullptr) {}
ListNode(int x) : val(x), next(nullptr) {}
ListNode(int x, ListNode *next) : val(x), next(next) {}
};
</code>
</pre>
<script src="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/components/prism-core.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/plugins/autoloader/prism-autoloader.min.js"></script>
<script
src="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/plugins/normalize-whitespace/prism-normalize-whitespace.min.js"
integrity="sha256-ronWqXsvaeyrdiX7YJfdYj0S5NbeMA5ilQQTrK25Jno="
crossorigin="anonymous"
></script>
</body>
</html>3、Vue3 中使用
npm install prismjs # 支持 typescript npm install @types/prismjs -D npm install vite-plugin-prismjs -D
vite.config.js 中配置
import prismjs from 'vite-plugin-prismjs';
export default defineConfig({
plugins: [
prismjs({
languages: ['javascript', 'css', 'html', 'json', 'sass', 'scss', 'md', 'bash', 'shell', 'ts'],
plugins: [
'toolbar',
'show-language',
'copy-to-clipboard',
'normalize-whitespace',
'line-numbers',
'unescaped-markup'
],
theme: 'tomorrow',
css: true
})
],
});基本使用

<template>
<pre class="line-numbers">
<code class='language-js'>
// JavaScript 代碼
function curry(func) {
return function curried(...args) {
if (args.length >= func.length) {
return func.apply(this, args);
} else {
return function(...args2) {
return curried.apply(this, args.concat(args2));
}
}
};
}
</code>
</pre>
</template>
<script setup>
import { onMounted } from 'vue';
import Prism from 'prismjs';
onMounted(() => {
Prism.highlightAll();
});
</script>
<style lang="scss" scoped></style>
補(bǔ)充
API
Prism.js 提供了一些 API
詳見:https://prismjs.com/docs/Prism.html#.manual
如:
highlight(text, grammar, language) → {string}
// 例子
Prism.highlight('var foo = true;', Prism.languages.javascript, 'javascript');

按鈕樣式調(diào)節(jié)
我們可能對代碼塊右上角按鈕的樣式不太滿意,可以對此進(jìn)行一定的調(diào)整。
如:

按鈕變?yōu)榉娇?,改變光?biāo)類型
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Prism Test</title>
<link href="prism.css" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="stylesheet" type="text/css" />
<style>
body {
margin: 0;
padding: 0;
height: 100vh;
}
div.code-toolbar > .toolbar {
opacity: 1;
}
.toolbar .toolbar-item span,
.toolbar .toolbar-item button {
border-radius: 0 !important;
margin: 0 6px;
}
.copy-to-clipboard-button:hover {
cursor: pointer;
}
</style>
</head>
<body>
<pre class="line-numbers">
<code class="language-js"
data-prismjs-copy="復(fù)制"
data-prismjs-copy-error="復(fù)制失敗"
data-prismjs-copy-success="復(fù)制成功"
>
let range = new Range();
range.setStart(p1.firstChild, 2);
range.setEndAfter(p2.firstChild);
document.getSelection().addRange(range);
</code>
</pre>
<script src="prism.js"></script>
</body>
</html>
Vue3 代碼高亮組件(僅供參考)
在 Vue3 中無法使用 <script type="text/plain" class="language-markup"> 方式高亮標(biāo)記語言。
如果需要實(shí)現(xiàn)一個代碼高亮組件的話 ,我們可以使用 <pre><code class="language-xxx"></code></pre> + slot 的方式渲染非標(biāo)記語言;
使用 <pre><code class="language-markup"></code></pre> + props + Prism.highlight + v-html 來渲染標(biāo)記語言。
高亮 script 標(biāo)簽
使用 <script type="text/plain" class="language-markup"> 方式高亮標(biāo)記語言時,如果要高亮 <script> 標(biāo)簽則需要轉(zhuǎn)義。
如

<script type="text/plain" class="language-markup"> <html></html> <p>Example</p> <div><button>Hello</button></div> <script></script> </script>
此外,在 Vue3 中通過 API 渲染 <script> 標(biāo)簽時,轉(zhuǎn)義后,可能會引起 eslint 報(bào)錯,可以通過配置 'no-useless-escape': 'off' 等方式解決,見 配置規(guī)則 - ESLint - 插件化的 JavaScript 代碼檢查工具。
總結(jié)
到此這篇關(guān)于前端語法高亮插件Prism.js使用詳細(xì)教程的文章就介紹到這了,更多相關(guān)前端語法高亮Prism.js使用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JS如何實(shí)現(xiàn)手機(jī)端輸入驗(yàn)證碼效果
這篇文章主要介紹了JS如何實(shí)現(xiàn)手機(jī)端輸入驗(yàn)證碼效果,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-05-05
使用JavaScript實(shí)現(xiàn)隨機(jī)顏色生成器
這篇文章主要為大家詳細(xì)介紹了如何使用JavaScript+CSS實(shí)現(xiàn)一個隨機(jī)顏色生成器,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以動手嘗試一下2022-08-08
微信小程序?qū)崿F(xiàn)上傳照片代碼實(shí)例解析
這篇文章主要介紹了微信小程序?qū)崿F(xiàn)上傳照片代碼實(shí)例解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-08-08
JavaScript簡單判斷復(fù)選框是否選中及取出值的方法
這篇文章主要介紹了JavaScript簡單判斷復(fù)選框是否選中及取出值的方法,涉及javascript遍歷復(fù)選框及元素取值的相關(guān)技巧,具有一定參考借鑒價值,需要的朋友可以參考下2015-08-08

