记录一下在 Vue.js 项目中使用 vue-prism-editor 进行语法高亮显示代码,并兼具代码编辑功能。JavaScript 中有几个比较典型的语法高亮显示的代码库,例如 SHJS, SyntaxHighlighter, Rainbow, highlight.js。本博客曾经使用过 SyntaxHighlighter 来显示日志中的示例代码,现今所采用的是基于 PHP 的 Crayon Syntax Highlighter。除了只为了高亮显示代码外,有时候还需处理在线编辑代码,许多年前试用过 CodeMirror, 而今天要上手 Prism.js 也能够支持代码编辑。
官方 Demo: prism-editor.netlify.com
Codesandbox: https://codesandbox.io/s/61yrlnlnmn。
为了给 Vue.js 项目提供方便,有人专门做了一个 Vue.js 的插件 vue-prism-editor,本文直接使用该插件,而非直接使用 Prism.js。并且项目蓝本用 @vue/cli 4.4.6
的命令
$ vue create vue-prism-editor-demo
创建的,创建过程可参考 Flask 和 Vue.js 开发及整合部署实例 的 创建 Vue 项目一节,此文简单些,就只选择 default (babel, eslint)
默认项来创建
完后启动服务
$ cd vue-prism-editor-demo
$ npm run serve
现在可访问 http://localhost:8080 来到了 Vue.js 的欢迎页面,接下来要应用 HelloWorld 页面来高亮显示代码。
先要安装 vue-prism-editor, 命令如下
$ npm install --save vue-prism-editor # 会连带安装 vue-prism-editor 的 css
$ npm install --save prismjs # 上一步并不会安装 prismjs, 所以需手动安装它,它也会同时安装 css
用 yarn
的话是 yarn add vue-prism-editor
。npm install
时候需要 --save 或 -S
,它会在 package.json
中的 dependencies
块中加上行
"vue-prism-editor": "^0.6.1",
"prismjs": "^1.20.0"
接下来只要对 App.vue
进行改造, App.vue
的完整内容如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
<template> <div id="app"> <prism-editor v-model="code" language="js" lineNumbers></prism-editor> </div> </template> <script> import VuePrismEditor from 'vue-prism-editor'; import 'vue-prism-editor/dist/VuePrismEditor.css'; import 'prismjs'; import 'prismjs/themes/prism.css'; import Vue from 'vue'; Vue.component('prism-editor', VuePrismEditor); export default { data() { return { code: `fetch('http://example.com/movies.json') .then(response => response.json()) .then(data => console.log(data)); `, }; }, }; </script> |
保存后,http://localhost:8080 自动刷新,现在看到的页面为
最后一行是直接在页面中输入的,证明那确实是一个 Editor, 是可编辑的,而且对于新输入内容也能进行实时的高亮显示。
vue-prism-editor 除了可编辑,语法加亮外,还有 Undo/Redo,大小自动调整,行号显示等。
我们可以切换显示主题,到底 prism 支持什么主题呢?查看 node_modules/prismjs/thems
目录下的文件
$ ls node_modules/prismjs/themes | sort
prism-coy.css
prism-dark.css
prism-funky.css
prism-okaidia.css
prism-solarizedlight.css
prism-tomorrow.css
prism-twilight.css
prism.css
于是我们可以把 App.vue
中的行
1 |
import 'prismjs/themes/prism.css'; |
改为上面列出的任一个主题样式,比如
1 |
import 'prismjs/themes/prism-twilight.css'; |
页面自动刷新,注意这时候要改用 Safari 之外的浏览器了, 反正 Safari 我测试是不支持样式的选择,换成 Chrome
如果要支持别的语言,可对 <prism-editor> 标签的 language 属性指定别的,如 java, json 等,查找当前 prism 支持哪些语言可用命令
ls node_modules/prismjs/components | grep 'min' | sort
列出,比如要支持 java,需先 import
1 |
import 'prismjs/components/prism-java'; |
然后
1 |
<prism-editor language="java></prism-editor> |
使用中发现的几个问题:
- 对 Safari 的支持较差,Safari 下初始时可高亮显示代码,但编辑代码时不能实时着色,并且不能切换主题
- 如果不是用
v-model="code"
的方式,而是:code="code"
, 在 Chrome 下编辑时也不能实时着色 - 显示大段代码时有问题,我测试的问题代码是 23M, 试图显示一个超大的 JSON 字符串,出现问题为
1234567891011121314151617181920vue.runtime.esm.js?2b0e:619 [Vue warn]: Error in render: "RangeError: Maximum call stack size exceeded"found in---> <PrismEditor><S3File> at src/views/S3File.vue<App> at src/App.vue<Root>vue.runtime.esm.js?2b0e:1888 RangeError: Maximum call stack size exceededat normalizeArrayChildren (vue.runtime.esm.js?2b0e:2384)at normalizeChildren (vue.runtime.esm.js?2b0e:2359)at _createElement (vue.runtime.esm.js?2b0e:3400)at createElement (vue.runtime.esm.js?2b0e:3353)at vm._c (vue.runtime.esm.js?2b0e:3491)at Proxy.render (VuePrismEditor.common.js?431a:2291)at VueComponent.Vue._render (vue.runtime.esm.js?2b0e:3548)at VueComponent.updateComponent (vue.runtime.esm.js?2b0e:4066)at Watcher.get (vue.runtime.esm.js?2b0e:4479)at Watcher.run (vue.runtime.esm.js?2b0e:4554)
这有点狠了,但目前还没有发现在超大内容时如何禁止语法高亮,所以加了个条件,凡是超过 5 M的字符串改用 textarea 来展示。
其他的 vue-prism-editor 相关的属性就只照抄官网了
属性
属性名 | 类型 | 默认值 | Options | Description |
---|---|---|---|---|
v-model | string |
- | - | 设置要显示的代码,编辑时能实时着色 |
code | string |
"" |
- | 要显示的代码,但编辑时不能实时着色 |
language | String |
"js" |
vue,html,md,ts + Prismjs Languages |
ls node_modules/prismjs/components | grep 'min' | sort | wc -l 查到能支持 210 种语言 |
lineNumbers | Boolean |
false |
- | 是否显示行号 |
readonly | Boolean |
false |
- | 是否只读 |
emitEvents | Boolean |
false |
- | 是否能触发事件 |
autoStyleLineNumbers | Boolean |
true |
- | 允许组件来设置行号的样式风格(不太明白) |
事件
Name | Parameters | Description |
---|---|---|
change | (code) |
当代码内容改变时触发 |
以下事件只有在 emitEvents
属性设置为 true
才会被触发
Name | Parameters | Description |
---|---|---|
keydown | (event) |
在编辑器中按下键时触发 |
keyup | (event) |
在编辑器中按键放开时触发 |
editor-click | (event) |
在可编辑时点击即触发 |
本文链接 https://yanbin.blog/vue-js-vue-prism-editor/, 来自 隔叶黄莺 Yanbin Blog
[版权声明] 本文采用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 进行许可。