LOGO OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 开发文档 其他文档  
 
网站管理员

使用语法高亮 Prism.js 让你写的代码美化起来(以Vue3为例)

admin
2024年3月29日 10:9 本文热度 661

tinymce编辑器界面

【tips】:tinymce是国外的一个功能超全开箱即用的富文本编辑器,他是一个开源的编辑器,除了基本的功能外还可以通过插件的形式拓展,插件也只需要简单的添加插件名称即可,插件分为开源插件和高级插件,其中高级插件功能需要付费,但开源的功能完全够用,而且提供了多种主题选择,还可以高度自定义编辑器样式,可以在 Vue、React、Angular、Blazor、Svelte、Node+Express等多种环境中使用。

下载地址:https://prismjs.com/download.html

目录

1.前台展示tinymce编辑器编辑的内容时踩的坑

2.安装PrimsJS代码高亮库

3.解决PrimsJS添加后代码不高亮的问题

4.给代码块添加行号

5.PrimsJS代码高亮的原理

一、前台展示tinymce编辑器编辑的内容时踩的坑

最近做了一个小项目,该项目主要是将tinymce富文本编辑器编辑的内容在前台展示,我很简单的以为只需要用Vue的v-html解析就能正常展示了,像下面这样

1. <template>

2.     <div class="article-wrapper">

3.         <template v-for="item in articleInfoData">

4.             <h2 class="title">{{ item.title }}</h2>

5.             <p class="desc" v-if="item.desc">摘要:{{ item.desc }}</p>

6.             <div class="content" v-html="item.content"></div>

7.             <p class="date">{{ item.created_at }}</p>

8.         </template>

9.     </div>

10.</template>

然而并没有那么简单,纯文本编辑的内容可以正常渲染,但是代码块就是显示纯文本,代码没有高亮,就像下面这样

这并非是我们所期待的,我们所期待的应该是下面这样的,让不同代码更加突出展示

后来才发现代码高亮是需要像prismjs这样的库来进行解析的,我们审查tinymce编辑器的代码块元素后会发现,pre->code标签下他给代码块添加了好多标签及样式,但是

我们获取到编辑器提交给后台的数据捶⑾謕re->code标签下就只有我们插入的代码块,就像下面这样,

起初我还以是tinymce编辑器配置的问题,导致缺失了pre->code标签下面的标签及样式,后来看完了tinymce官方文档的配置也没有找到类似的配置。

二、安装Prismjs代码高亮库

后来在网上找到了代码高亮库prismjs并愉快的添加到了Vue3+Ts项目中

什么是prismjs

官方是这样描述的,他是一个非常简单快速可拓展且支持超多语言的轻量级代码高亮库。官网地址

1. //安装

2. npm install prismjs

1. //引入Prism(我们只需要在局部引入即可,我这里是在文章内容展示组件中引入)

2. <script setup lang="ts">

3. import { ref, reactive, onMounted } from 'vue'

4. import type {Ref } from 'vue'

5. import { useRouter, useRoute } from 'vue-router'

6. import { api } from "@/assets/config/api"

7. import { request } from "@/assets/common/request"

8. import Prism from "prismjs"//导入代码高亮插件的core(里面提供了其他官方插件及代码高亮样式主题,你只需要引入即可)

9. import "prismjs/themes/prism-tomorrow.min.css"//引入代码高亮主题(这个去node_modules的安装prismjs中找到想使用的主题即可)

10.

11.const router = useRouter()

12.const route = useRoute()

13.const articleInfoData: Ref<Array<object>> = ref([]);

14.

15.onMounted(() => {

16.   getArticleInfo()

17.   Prism.highlightAll()// 全局代码高亮

18.})

19.function getArticleInfo(): void {//从后台请求数据

20.        request.get(api.GetArticleInfo, {

21.            id: route.params.id

22.        }).then(res => {

23.          articleInfoData.value = res?.data?.data

24.        }).catch(err => {

25.           console.log(err)

26.        })

27.    })

28.

29.}

30.</script>

但结果又出现了下面的这种问题,明显可以看到prismjs以及css是被加载了的,但代码还是没有被高亮

后来研究才发现是因为prismjs执行的时机不对导致pre->code中的代码没有被prismjs解析添加相应的标签。

三、解决PrimsJS添加后代码不高亮的问题

解决办法也很简单,我们可以给Prismjs高亮方法添加一个定时器延迟加载,或者使用

1. onMounted(() => {

2.     getArticleInfo()

3.      setTimeout(() => {

4.         Prism.highlightAll()// 全局代码高亮

5.     }, 100)

6. })

async/await配合Promise进行加载,等数据完全加载完后再用Prismjs进行解析即可实现代码高亮,就像下面那样(需要注意的是一定要等v-html中后台返回的数据加载完毕后才可以被Prismjs解析)

1. <script setup lang="ts">

2. import { ref, reactive, onMounted } from 'vue'

3. import type {Ref } from 'vue'

4. import { useRouter, useRoute } from 'vue-router'

5. import { api } from "@/assets/config/api"

6. import { request } from "@/assets/common/request"

7. import Prism from "prismjs"//代码高亮插件的core

8. import "prismjs/themes/prism-tomorrow.min.css"//高亮主题

9. const router = useRouter()

10.const route = useRoute()

11.const articleInfoData: Ref<Array<object>> = ref([]);

12.onMounted(async () => {

13.   await getArticleInfo().then(res => {

14.        articleInfoData.value = res

15.    }).catch(err => {

16.       console.log(err);

17.    })

18.     Prism.highlightAll()// 全局代码高亮(必须等获取数据之后,代码高亮才能生效,也可以用定时器定时)

19.})

20.function getArticleInfo(): Promise<Array<object>> {//从后台请求数据

21.   return new Promise((resolve, reject) => {

22.        request.get(api.GetArticleInfo, {

23.            id: route.params.id

24.        }).then(res => {

25.            resolve(res?.data?.data)

26.        }).catch(err => {

27.            reject(err)

28.        })

29.    })

30.}

31.</script>

四、给代码块添加行号

我们从上图中可以发现虽然我们完美的给代码添加理论高亮,但我们在vscode中使用时会发现,每行代码都有相应大行号,这样代码出错时我们可以直接定位到某一行。

我们可以看到Prism官方 https://prismjs.com/index.html#plugins 提供了一些常用的插件,我们选择红框中的行号

那么如何使用行号插件呢?其实很简单,我们刚刚在上文中安装了Prism,只需要在node_modules中找到刚刚安装的prismjs中的plugins,然后找到对应的插件引入即可。

在项目中需要这样引入

1. <script setup lang="ts">

2. import { ref, reactive, onMounted } from 'vue'

3. import type {Ref } from 'vue'

4. import { useRouter, useRoute } from 'vue-router'

5. import { api } from "@/assets/config/api"

6. import { request } from "@/assets/common/request"

7. import Prism from "prismjs"//代码高亮core

8. import "prismjs/plugins/line-numbers/prism-line-numbers.min.js"//行号插件

9. import "prismjs/themes/prism-tomorrow.min.css"//高亮主题

10.import "prismjs/plugins/line-numbers/prism-line-numbers.min.css"//行号插件的样式

11.const router = useRouter()

12.const route = useRoute()

13.const articleInfoData: Ref<Array<object>> = ref([]);

14.onMounted(async () => {

15.   await getArticleInfo().then(res => {

16.        articleInfoData.value = res

17.    }).catch(err => {

18.       console.log(err);

19.    })

20.   Prism.highlightAll()// 全局代码高亮(必须等获取数据之后,代码高亮才能生效,也可以用定时器定时)

21.})

22.function getArticleInfo(): Promise<Array<object>> {//从后台请求数据

23.   return new Promise((resolve, reject) => {

24.        request.get(api.GetArticleInfo, {

25.            id: route.params.id

26.        }).then(res => {

27.            resolve(res?.data?.data)

28.        }).catch(err => {

29.            reject(err)

30.        })

31.    })

32.}

33.</script>

引入完之后刷新你会发现还是没有添加行号

官网已经说得很清楚,除了引入行号插件及样式,我们还需要指定一个line-numbers类,将这个类添加到pre标签或者他的祖先,只要他或他的祖先添加的了line-numbers那么他的子元素就会被行号插件自动添加line-numbers,从而达到添加行号。

添加line-numbers类名到自己的项目,在这里我添加到了v-html要解析的那个标签上,因为后台返回的编辑数据都是在该标签内渲染,所以该标签属于pre标签的祖先元素,你也可以将line-numbers类名添加到该div的祖先父级元素中,又或者可以添加到body上,但建议添加到这个v-html要渲染的签上,因为只有该标签内的数据是要被渲染解析的。

1. <template>

2.     <div class="article-wrapper">

3.         <template v-for="item in articleInfoData">

4.             <h3 class="title">{{ item.title }}</h3>

5.             <p class="desc" v-if="item.desc">摘要:{{ item.desc }}</p>

6.             <section class="author">

7.                 <span>作者:三叶雨</span>&nbsp;

8.                 <span>{{ item.created_at }}</span>

9.             </section>

10.            <div class="content line-numbers" v-html="item.content"></div>

11.        </template>

12.    </div>

13.</template>

添加line-numbers类名后我们可以看到行号已经被添加上去,其他插件的使用方式同本插件,大家按需引入然后看对应的插件即可。

五、Prismjs代码高亮的实现原理

在说原理之前我们应该弄明白的一个问题是,编辑器编辑的内容输出数据格式是怎么样的,这里以tinymce编辑器为例,我们可以发现返回给前台的数据是这样的,我们可以发现代码块被pre->code被这两个标签所包裹,简单来说就是prismjs是在pre->code

从后台返回的编辑器内容数据

上做了一些处理,我们可以从prismjs的源码中可以发现,获取到pre->code之后,首先获取到pre标签类上的language-xxxx给对应语言的关键字用正则匹配替换或添加标签及相应的样式,这样就达到了代码高亮的效果。

prism解析js的源码

被prism解析后代码高亮的HTML源码

所以只要符合pre->code标签结构内的代码块都会被prism js解析高亮。

到此完结,希望能为你节省一些时间。


该文章在 2024/3/29 10:17:23 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2024 ClickSun All Rights Reserved