如何在代码中让按钮高亮_各种博客的代码高亮是如何实现的
本文來自 「Vue虛擬實(shí)驗(yàn)」的小伙伴? 余xiaoy,在做 Lovue 項(xiàng)目的時(shí)候,他負(fù)責(zé)了代碼高亮顯示功能,目前實(shí)現(xiàn)了代碼高亮、主題切換、某行代碼特殊顯示、顯示行號(hào)等功能,效果如下。
下面介紹如何通過 Vue 來完成這個(gè)功能:Vue 為我們提供了很方便的創(chuàng)建組件的方式,組件化開發(fā)能夠?qū)I(yè)務(wù)進(jìn)行解耦,進(jìn)而提高項(xiàng)目的開發(fā)效率。在 Vue 中定義組件非常簡單:定
<div?id="app">????????<lovue>lovue>div><script>????//?1.?使用Vue.component(name,{})進(jìn)行組件全局注冊(cè)????Vue.component('lovue',?{ template: '這是lovue組件
'????})l????const?vm?=?new?Vue({????????el:?'#app',????????data:?{},????????methods:?{} });script>以上代碼便定義了一個(gè)全局的 lovue 組件,隨后我們可以很愉快地在頁面各個(gè)位置通過引入 lovue 標(biāo)簽的形式使用我們的組件了。
對(duì)于 demo 型項(xiàng)目,采用這種方式是可以的,但這種形式缺點(diǎn)很明顯,比如字符串模板無法代碼高亮,無法單獨(dú)定義 CSS 樣式等。因此在實(shí)際的項(xiàng)目當(dāng)中,我們更多的是采用單文件組件的形式來定義組件。
1、單文件組件
在 Vue 中,一個(gè).vue 文件就是一個(gè)單文件組件,一個(gè)基本的單文件組件代碼結(jié)構(gòu)如下:
<template> <div> <h3>這是lovue單文件組件h3> div>template><script>export default { // JS代碼部分,包含組件內(nèi)定義的屬性及方法 name: "Lovue", data() { return {}; }};script><style scoped>/* CSS代碼,添加scoped屬性將定義為局部樣式 */style>將內(nèi)嵌的組件定義改造為單文件組件形式后,我們可以在其他頁面中,通過 import 語法進(jìn)行導(dǎo)入,并采取全局或者局部的方式進(jìn)行注冊(cè):
import Lovue from '@/components/Lovue'// 1.全局注冊(cè)Vue.components('lovue', Lovue)// 2.Vue實(shí)例內(nèi)部局部注冊(cè)const vm = new Vue({ el: '#app', components: { Lovue }})使用單文件組件,能讓我們的項(xiàng)目文件結(jié)構(gòu)較為清晰,使用 vue-cli創(chuàng)建的項(xiàng)目,腳手架已經(jīng)幫我們創(chuàng)建好了專門放置組件的文件夾 `components` 和 `views` ,`components` 一般用來放置小型組件,在其他頁面可能會(huì)被多次引用,`views`用來放置頁面級(jí)組件,一般不可復(fù)用。
2、代碼高亮組件實(shí)現(xiàn)(基于?Prismjs)
學(xué)會(huì)使用單文件組件后,我們便可以定制自己的組件了。在 Lovue 項(xiàng)目,我們便創(chuàng)建了代碼高亮組件,其功能是針對(duì)指定的代碼塊進(jìn)行高亮顯示,同時(shí)組件還實(shí)現(xiàn)了代碼塊內(nèi)部的局部代碼高亮及代碼塊的主題切換功能,下面使用迭代的思想介紹該組件的實(shí)現(xiàn)過程。
創(chuàng)建組件之前,我們需要清楚組件的使用場景,這樣能讓我們更好地對(duì)組件功能進(jìn)行劃分,并從用戶角度去設(shè)計(jì)一款體驗(yàn)良好的組件。
具體到 Lovue 的代碼高亮組件,我們需要能夠?qū)ξ恼伦髡咧付ǖ拇a塊進(jìn)行高亮顯示,同時(shí)對(duì)于代碼塊中的重點(diǎn)代碼區(qū)域可以進(jìn)行著重顯示,這樣對(duì)于文章的讀者來說,可以很快速的了解到作者想講解的代碼片段。同時(shí),為了適應(yīng)不同讀者對(duì)于代碼顯示風(fēng)格的喜好,組件還需實(shí)現(xiàn)多種預(yù)定義主題的切換功能。
分析完成后,我們就可以開始創(chuàng)建代碼高亮組件了。
對(duì)于代碼高亮功能的實(shí)現(xiàn),目前已有像 Prismjs, highlight.js 等比較成熟,使用程度較高的庫了,這里我們選用 Prismjs 來實(shí)現(xiàn)我們的代碼高亮組件。
因?yàn)檫x用了第三方庫,因此第一步我們需要將 Prismjs 引入到我們的項(xiàng)目當(dāng)中:
npm i prismjs babel-plugin-prismjs -Sprismjs 為核心庫,babel-plugin-prismjs 可以配置 prismjs 附帶的多種插件;若 npm 下載慢,可以使用 cnpm
安裝完成后,我們需要更新項(xiàng)的目配置文件 babel.config.js,添加如下配置項(xiàng):
"plugins": [ ["prismjs", { "languages": ["html", "javascript", "css", "markup"], "css": true } ] ]以上配置定義了我們需要高亮顯示的代碼語言,配置好之后,我們就可以搭建我們組件的代碼了。
<template> <pre>?????????<code?class="language-javascript"> const vm = new Vue({ el: '#app', data: {}, methods: {} })??????code>?pre>template><script>import Prism from "prismjs";export default { name: "CodeHighLight", mounted() { // Prismjs內(nèi)置的代碼高亮方法 Prism.highlightAll(); }};script><style>style>上述代碼通過僅使用 Prismjs 庫自帶的方法,已經(jīng)實(shí)現(xiàn)了一個(gè)最基本且可用的代碼高亮組件了。是的,就是這么簡單,你現(xiàn)在可以在你的頁面中引入這個(gè)組件了,如無意外,你將看到如下效果:
但該組件目前過于簡單,且代碼塊寫死在組件中,用戶無法自定義,因此需要在此基礎(chǔ)上進(jìn)行改進(jìn)。這是一個(gè)很好的做項(xiàng)目/寫代碼的方式,首先實(shí)現(xiàn)最基本的功能,然后在此基礎(chǔ)上進(jìn)行更新迭代,慢慢添加新的功能。
考慮我們前面分析的使用場景,用戶在父頁面中引入我們的組件時(shí)可定義自己的代碼塊,因此該代碼塊是在父組件中定義,但是要在子組件中可以使用的。解決這個(gè)問題,我們需要使用到 Vue 中常用的父子組件傳值方法,群里其他同學(xué)分享過具體的使用,這里不再贅述,直接上代碼:
<template> <div> <pre v-if="code"> <code :class="codeClass" v-text="code">code> pre> div>template><script>import Prism from "prismjs";import "prismjs/themes/prism-tomorrow.css";export default { name: "CodeHighLight", props: { // 父組件的代碼塊變量 code: { type: String, required: true }, // 代碼語言,默認(rèn)為JS lang: { type: String, default: "javascript" } }, computed: { codeClass: function() { return "language-" + this.lang; } }, mounted() { Prism.highlightAll(); }, updated() { Prism.highlightAll(); }};script><style>style>這里我們將從父頁面?zhèn)鬟f過來的 code 變量設(shè)置為必需項(xiàng),若用戶未定義,則控制臺(tái)打印錯(cuò)誤。同時(shí)考慮我們使用 javascript 語言較多,我們將代碼語言默認(rèn)設(shè)置為 javascript。
代碼改造后,我們就可以通過以下方式在父頁面中使用了,其中 code,code1 為用戶定義的代碼變量:
:code="code"> :code="code1" lang=如無意外,你可以在頁面中可看到類似下面的效果:
到這里,其實(shí)用戶已經(jīng)可以使用該組件了,但為了更好的用戶體驗(yàn)及提高組件的靈活性,我們還需要在此基礎(chǔ)上進(jìn)行進(jìn)一步的更新迭代。
可選的但不限于:顯示代碼的行號(hào),顯示代碼的語言,對(duì)代碼塊中的局部代碼進(jìn)行著重顯示等。
查閱 Prismjs 官方文檔后發(fā)現(xiàn),官方已經(jīng)為我們提供了很多可選的插件,找到對(duì)應(yīng)的插件名后,我們就可以在 babel.config.js 中對(duì) prismjs 的插件進(jìn)行配置了。
'plugins': [ ["prismjs", { "languages": ['html', "javascript", "css", "markup"], "plugins": ['match-braces', 'autolinker', 'inline-color', 'normalize-whitespace', 'copy-to-clipboard', 'show-language', 'line-numbers', 'line-highlight'], "css": true } ] ]以上的插件名及對(duì)應(yīng)的作用可以查閱 Prismjs 官方文檔,完成插件配置后,我們需要增加幾個(gè)組件的 prop,用于接收父組件定義的局部高亮代碼行數(shù),高亮背景色等變量,具體可到 Lovue 項(xiàng)目 github 倉庫查看。
至此,我們重啟項(xiàng)目,已經(jīng)可以看到類似下面的效果了:
效果不錯(cuò),保存好這版代碼,我們繼續(xù)往下,看下如何實(shí)現(xiàn)代碼高亮主題切換的功能。
Vue 本身為我們提供了 class 及 style 的數(shù)據(jù)綁定功能,也有同學(xué)分享過相關(guān)的使用方法。但因?yàn)?Prismjs 的內(nèi)部實(shí)現(xiàn)是將用戶代碼根據(jù)語言類型解析并拆分成不同的字符分組,然后針對(duì)不同分組在其上應(yīng)用不同的 class。在 Prismjs 提供的不同主題文件中,相同分組的 class 名均相同,因此我們無法直接通過使用 class 數(shù)據(jù)綁定的形式進(jìn)行主題的切換。
使用該思路,一種可行的方式是采用 Scss 等 css 預(yù)編譯工具對(duì)不同主題的 css 代碼統(tǒng)一增加前綴 class 類名(不同主題類名不同),然后使用數(shù)據(jù)綁定功能進(jìn)行類名/主題切換。但操作起來很不方便,這里不討論。
這里采用另一種方式,在頁面中通過 link 標(biāo)簽引入主題 css 文件,在用戶切換不同的主題時(shí),替換 link 標(biāo)簽的 href 值為對(duì)應(yīng)的主題 css 文件,實(shí)現(xiàn)代碼主題切換。該方式的核心代碼如下,感興趣的可到 Lovue 項(xiàng)目倉庫查看:
methods: { addCss(theme) { let link = document.createElement("link"); let head = document.getElementsByTagName("head")[0]; link.rel = "stylesheet"; link.type = "text/css"; link.href = this.cssPrefix + theme + ".css"; head.appendChild(link); }, loadCss(theme) { let cssLink = "link[href^='" + this.cssPrefix + "']"; let link = document.head.querySelectorAll(cssLink); if (link.length) { // 判斷主題css文件是否存在 for (let i = 0; i < link.length; i++) link[i].href = this.cssPrefix + theme + ".css"; return; } this.addCss(theme); console.log("loadCss done."); }},watch: { // 監(jiān)聽theme變化,加載對(duì)應(yīng)主題的css文件 theme: function(newVal) { this.loadCss(newVal); localStorage.setItem("codeTheme", newVal); }},mounted() { this.loadCss(theme);}這里使用了?localStorage?來讀取和保存用戶選擇的主題,可提升用戶體驗(yàn)
至此,Lovue 項(xiàng)目中的代碼高亮組件已基本完成。整個(gè)過程不復(fù)雜,感興趣的可以動(dòng)手創(chuàng)建屬于自己的組件了。
推薦閱讀:不寫一行代碼,即可跨域的技巧Vue 模板的功臣 · 指令第六階段 · 期待已久的 Vue第四階段 · JavaScript 專題結(jié)束,有電子書
總結(jié)
以上是生活随笔為你收集整理的如何在代码中让按钮高亮_各种博客的代码高亮是如何实现的的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java分隔符算法_《Java数据结构和
- 下一篇: 挖掘城市ip_抖in杭州嘉年华,原来城市