前端显示代码高亮

前端显示代码高亮

Time:2021-3-22

前言

搭建博客网站的过程还真是多bug…什么奇奇怪怪的问题都有,很大原因就是这个VueCLI版本太高级了…都没什么关于这个版本的使用的资料,中文的官方文档简单的就好像什么都没说,基本的vue语法就那样,但是工程的结构和一些关键API却没有详细说明,难受。使得我总是只能自己不断揣测和尝试。这个代码高亮也是,搞了两天,终于才觉悟问题何在。

转载请注明出处!!!

Author:雾雨霜星
欢迎来我的个人网站进行学习:
https://www.shuangxing.top/#/passage?id=16

highlight.js

这是前段最多人使用的代码高亮的依赖了,确切来说他仅仅是一个js文件,里面封装了可以处理代码高亮的函数,主要有:

  • highlightBlock(block):

    • 说明:对包含代码的 DOM 节点添加高亮标记。默认使用语言检测,但是你也可以在节点上添加 class 属性来指定语言。

    • 参数:block是DOM节点

  • initHighlighting():

    • 说明:为页面中所有 <pre><code>..</code></pre> 块添加高亮标记。配合 styles 中的 css 使用即可实现着色。
  • highlightAll():

    • 说明:自动处理整个页面所有的 <pre><code>..</code></pre> 部分,进行代码高亮,感觉效果与前者一样。

在网上,目前大部分使用highlight的思路是:

  1. 使用npm安装引入
  2. 定义全局指令 v-highlight
  3. 全局指令中通过找到<pre><code>..</code></pre>调用highlightBlock(block)函数进行处理

可以说这是使用highlight最好的思路,因为在vue路由切换后即使是异步请求的数据仍然可以使用vue指令使得代码高亮生效。

但是他们的方法里面有个问题,就是使用了Vue.use,这是VueCLI3以前常见的方法,但是在VueCLI4.5中如果这样做,会报错,或者发现指令没有效果。解决办法如下详述,

VueCLI4.5中Vue实例的建立

因为在VueCLI4.5中是隐式建立App实例,在main.js可以看到:

import { createApp } from 'vue'
import App from './App.vue'
import router from './router'

createApp(App).use(router).mount('#app')

根本没有Vue实例直接给出,直接import Vue from ‘vue‘?不行的,指令不会有效果的。

所以就要聪明点,改写为显式的,但是直接按照VueCLI2的写法,会报错。

我就试着这样写,定义常量作为这个createApp的API输出:

import { createApp } from 'vue'
import App from './App.vue'
import router from './router'

const app = createApp(App)
app.use(router)
app.mount('#app')

经过测试,这样写没有任何问题。

在这里,原本常写的Vue实例Vue,其实只是换了个名字叫app而已。同样都是以App作为组件来建立的。

highlight实现

那么就直接记录关于如何使用highlight.js来实现代码高亮吧。
参考:

  • https://blog.csdn.net/qq_43332570/article/details/107079382
  • https://www.jianshu.com/p/6c1e4fcc6d6f
  • https://blog.csdn.net/Cribug8080/article/details/101370107
  1. 安装引入:

    使用npm进行安装,在终端输入:

    npm install highlight.js --save-dev
    

    或者VueCLI3以上可以进入Vue ui中,在依赖项选择添加依赖,查找后进行安装即可。

  2. 配置全局指令:

    主要是在main.js中,在进行实例初始化之前进行配置。

    如果是VueCLI2的工程,如下:

    import Vue from 'vue'
    import App from './App'
    import router from './router'
    
    import hljs from 'highlight.js'
    import 'highlight.js/styles/dracula.css'
    
    Vue.config.productionTip = false
    
    // 定义一个全局指令
    Vue.directive('highlight',function (el) {
      let blocks = el.querySelectorAll('pre code');
      blocks.forEach((block)=>{
        hljs.highlightBlock(block)
      })
    })
    
    
    new Vue({
      el: '#app',
      router,
      render: h => h(App)
    })
    
    

    注意要import得到’highlight.js’和相应的代码高亮风格的css文件。

    对于VueCLI4.5的如下:

    import { createApp } from 'vue'
    import App from './App.vue'
    import router from './router'
    import hljs from "highlight.js"
    
    import 'highlight.js/styles/github-gist.css'
    
    /*createApp(App).use(router).mount('#app')*/
    
    const app = createApp(App)
    app.use(router)
    app.mount('#app')
    
    // 定义一个全局指令 v-highlight:用于显示代码高亮
    app.directive('highlight',function (el) {
        let blocks = el.querySelectorAll('pre code');
        blocks.forEach((block)=>{
            hljs.highlightBlock(block)
        })
    })
    

    我这里之所以使用el.querySelectorAll(‘pre code’);是因为在Typora得到的markdown文件,里面代码部分都是这个格式的,所以我就对这部分进行代码高亮。

  3. 使用指令:

    如果是对html内容进行代码高亮,就使用过刚才定义的指令,对相应div进行使用即可,例如:

    <template>
    <div>
      <div id="passage-main-area" v-html="passage_article" v-highlight></div>
    </div>
    </template>
    

    如果只是普通的<pre><code>..</code></pre>部分,即不在html中,那么直接在相应组件内import得到highlight.js然后在mounted生命周期函数中调用highlight.js的highlightAll()函数即可,如果是在路由,那么应该还需要调用initHighlighting()函数,最好全都调用吧。

    <template>
    <div>
      <pre><code>xxxx</code></pre>
    </div>
    </template>
    ... ...
    <script>
    import hljs from 'highlight.js'
    ... ...
      mounted() {
      hljs.highlightAll();
      hljs.initHighlighting();
      }
    }
    </script>
    ... ...
    

    注意记得style中还需要通过@import引入highlight.js/style中的样式才能有效果。

小插曲

我已经不记得自己试了多少方法了。

一开始要用指令进行实现的时候,就已经折腾了无数次了,后来看到一个把highlight.js插件化调用的方法,即写了一个js用于进行自定义指令声明,然后export出去给Vue实例use,可惜我当时,想到了改写那个createApp的API生成实例的方法,用了app.use也还是没有成功,因为在那里面进行指令声明是Vue.directive,但是其实根本没有Vue这个名字的实例,只是import Vue from ’vue‘是没有真的实例的。

按照在组件中import引入highlight.js和相应的css文件,然后直接在mounted钩子中使用那两个全局的代码高亮函数,可以实现普通的pre和code组合元素内代码高亮,但是通过我axios从后端请求得到的html,这样就没有效果,指令也不生效。

还试过,企图通过DOM操作获取div中的pre和code,然后直接在生命周期函数中调用highlightBlock(block)函数进行处理,但是,搞了一个早上也还是没能够成功得到这个子节点,我都想要不要对子节点列表循环比较进行获取了。

然后我吃了个饭,回来后直接觉悟,是我的Vue实例名字的问题!试试改写!才成功实现了通过指令进行代码高亮。

转载请注明出处!!!

Author:雾雨霜星
欢迎来我的个人网站进行学习:
https://www.shuangxing.top/#/passage?id=16

PS: 毕竟,霜星酱水平有限,如果发现任何错误还请及时邮箱告知我,我会去改哦!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值