Vue3 造轮子之 Typescript 配置 highlight

项目基础是 vue3+typescript 实现一个简单的 UI 组件库。
在编写组件介绍文档时,需要提供一些代码示例,这时候用到了 hightlight.js 来实现代码的高亮。

一、安装 highlight.js

执行命令行进行依赖以及类型声明的安装

yarn add highlight.js @types/highlight.js

安装完成后,按照官方地址配置发现是无法使用的,报错情况如下

在这里插入图片描述这个问题说明我们引入的类并没有 vuePlugin 这个属性

二、增加 highlight.ts 文件

那么我们基于 typescript 来使用 highlight.js 的话,就需要解决这个 vue.use() 的问题。

查阅资料得知,需要增加一个定义 vue 外部插件的 highlight.ts

如下所示,可放心复制

import Hljs from 'highlight.js';
import 'highlight.js/styles/monokai-sublime.css'
// 自定义的interface会导致报错
// interface Highlightjs {
//    [x:string]:any
// }
//let Highlight:Highlightjs = {};
let Highlight:any = {};

Highlight.install = function (Vue:any,options:any) {

    Vue.directive('highlightA',{
        inserted:function(el:any){
            let blocks = el.querySelectorAll('per code');
            for (let i = 0; i < blocks.length; i++) {
                const item = blocks[i]
                Hljs.highlightBlock(item)
            }
        }
    })

    Vue.directive('highlightB',{
        componentUpdated:function(el:any){
            let blocks = el.querySelectorAll('per code');
            for (let i = 0; i < blocks.length; i++) {
                const item = blocks[i]
                Hljs.highlightBlock(item)
            }
        }
    })
}

export default Highlight

在这里曾尝试定义一个 Highlightjs 的接口类型,但是会导致报如下的错误,而放弃
在这里插入图片描述初步分析该报错的原因是 interface 里的类型定义还是存在一定的问题,所以用了 any 类型暴力解决了。

三、在入口文件引入

定义好 highlight.ts 文件后,在我们的入口文件 main.ts 中引入即可

下面的代码可放心复制

import { createApp } from 'vue'
import router from './router'
import App from './App.vue'
import Highlight from './libs/types/highlight' // 路径对应你创建的highlight.ts的路径

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

到此,我们就可以在 ts 文件中正常的引入 hightlight.js 并开始使用了。

个人测试验证第二、第三步不可行,以下是更正后的方法

四、在入口文件注册指令

安装好 highlight.js 之后,我们在入口文件注册 vue 的自定义指令 directive

代码如下

import { createApp } from 'vue'
import router from './router'
import App from './App.vue'
import hljs from 'highlight.js'
import 'highlight.js/styles/monokai-sublime.css'

const app = createApp(App)
app.use(router)

// 注册自定义指令高亮代码
app.directive('highlight', {
  // Directive has a set of lifecycle hooks:
  // called before bound element's parent component is mounted
  beforeMount(el:any) {
    // on first bind, highlight all targets
    let blocks = el.querySelectorAll('pre code');
    for(let i = 0 ;i < blocks.length ; i++){
      let item = blocks[i]
      console.log(item)
      hljs.highlightBlock(item)
    }
  },
  // called after the containing component's VNode and the VNodes of its children // have updated
  updated(el:any, binding:any) {
    // after an update, re-fill the content and then highlight
    let targets = el.querySelectorAll('code');
    for (let i = 0; i < targets.length; i += 1) {
        let target = targets[i];
        if (typeof binding.value === 'string') {
        target.textContent = binding.value;
        }
        hljs.highlightBlock(target);
    }
  }
})

app.mount('#app')

这样我们在组件中可以通过指令进行代码高亮的编写了,示例如下

<pre v-highlight>
  <code class="javascript">
    let a = "hello world";
    console.log(a)
  </code>
</pre>

参考博客

Vue3官网文档
Vue3.0 + Typescript 使用 Vue.use(Highlight) 问题记录

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值