Vue3 代码块高亮显示并可使用富文本编辑器编辑(highlight.js + wangEditor)
在Vue项目中实现以下功能:
功能1. 在页面中显示代码,并将其中的关键字高亮显示。
功能2. 允许对代码块进行编辑,编辑时代码关键字也高亮显示。
功能3. 可在编辑器中添加多个代码块,动态渲染代码关键字高亮。
Step1: 安装所需插件(本文使用npm安装,若需使用其他方式请查阅官方文档)
安装代码高亮显示插件highlight.js,官方网站:http://highlight.cndoc.wiki
npm install highlight.js
安装highlight.js与vue的集成插件highlightjs/vue-plugin,官方文档:https://github.com/highlightjs/vue-plugin
注意:本文编写时,以下命令会自动安装2.1.0版本,为vue2对应版本,使用vue3需手动将package.json中版本改为2.1.2版本。
npm install @highlightjs/vue-plugin
安装富文本编辑器插件wangEditor,以及对应的vue集成插件,官方网站:https://www.wangeditor.com/
npm install @wangeditor/editor
npm install @wangeditor/editor-for-vue@next
Step2:使用highlight.js实现功能1 -- 在页面中显示代码,并将其中的关键字高亮显示。
<script setup lang="ts">
import { ref } from 'vue';
import 'highlight.js/styles/stackoverflow-light.css'
import 'highlight.js/lib/common';
import hljsVuePlugin from "@highlightjs/vue-plugin";
const code = ref(`let hello = 'Hello World!';
console.log(hello);`)
</script>
<template>
<hljsVuePlugin.component :code="code" />
</template>
页面效果
Step3:使用wangEditor实现功能2 -- 允许对代码块进行编辑,编辑时代码关键字也高亮显示。
<script setup lang="ts">
import { onBeforeUnmount, ref, shallowRef } from 'vue';
import '@wangeditor/editor/dist/css/style.css';
import { Editor, Toolbar } from '@wangeditor/editor-for-vue';
const editorRef = shallowRef();
const valueHtml = ref(`<pre id="w-e-element-18" data-slate-node="element"><code id="w-e-element-19" data-slate-node="element"><span id="w-e-text-20" data-slate-node="text"><span data-slate-leaf="true"><span data-slate-string="true" class="token keyword">let</span></span><span data-slate-leaf="true"><span data-slate-string="true"> hello </span></span><span data-slate-leaf="true"><span class="token operator" data-slate-string="true">=</span></span><span data-slate-leaf="true"><span data-slate-string="true"> </span></span><span data-slate-leaf="true"><span class="token string" data-slate-string="true">'Hello World!'</span></span><span data-slate-leaf="true"><span class="token punctuation" data-slate-string="true">;</span></span><span data-slate-leaf="true"><span data-slate-string="true">
console</span></span><span data-slate-leaf="true"><span class="token punctuation" data-slate-string="true">.</span></span><span data-slate-leaf="true"><span data-slate-string="true" class="token function">log</span></span><span data-slate-leaf="true"><span class="token punctuation" data-slate-string="true">(</span></span><span data-slate-leaf="true"><span data-slate-string="true">hello</span></span><span data-slate-leaf="true"><span class="token punctuation" data-slate-string="true">)</span></span><span data-slate-leaf="true"><span class="token punctuation" data-slate-string="true">;</span></span></span></code></pre>`);
const toolbarConfig = {
excludeKeys: []
}
const editorConfig = { placeholder: '请输入内容...' }
// 组件销毁时,也及时销毁编辑器
onBeforeUnmount(() => {
const editor = editorRef.value
if (editor == null) return
editor.destroy()
})
const handleCreated = (editor: any) => {
editorRef.value = editor // 记录 editor 实例,重要!
}
</script>
<template>
<div>
<Toolbar style="border-bottom: 1px solid #ccc" :editor="editorRef"
:defaultConfig="toolbarConfig" mode="default"/>
<Editor style="height: 500px; overflow-y: hidden;" v-model="valueHtml"
:defaultConfig="editorConfig" mode="default" @onCreated="handleCreated"/>
</div>
</template>
页面效果
Step4:使用结合highlight.js和wangEditer实现功能3 -- 可在编辑器中添加多个代码块,动态渲染代码关键字高亮。
<script setup lang="ts">
import { onBeforeUnmount, ref, shallowRef } from 'vue';
import 'highlight.js/styles/stackoverflow-light.css'
import 'highlight.js/lib/common';
import hljs from "highlight.js";
import '@wangeditor/editor/dist/css/style.css';
import { Editor, Toolbar } from '@wangeditor/editor-for-vue';
const editMode = ref(true);
//定义指令,自动使用highlight.js渲染所有<pre><dode>代码块
const vHigelight = {
mounted(el :any) {
let blocks = el.querySelectorAll('pre code');
blocks.forEach((block: HTMLElement)=>{
block.setAttribute('style', 'margin-top: 8px;');
hljs.highlightBlock(block)
})
}
}
const editorRef = shallowRef();
const valueHtml = ref('');
const toolbarConfig = {
excludeKeys: []
}
const editorConfig = { placeholder: '请输入内容...' }
// 组件销毁时,也及时销毁编辑器
onBeforeUnmount(() => {
const editor = editorRef.value
if (editor == null) return
editor.destroy()
})
const handleCreated = (editor: any) => {
editorRef.value = editor // 记录 editor 实例,重要!
}
</script>
<template>
<div v-if="!editMode">
<button @click="editMode = true">编辑</button>
<div v-higelight v-html="valueHtml"></div>
</div>
<div v-if="editMode">
<button @click="editMode = false">保存</button>
<Toolbar style="border-bottom: 1px solid #ccc" :editor="editorRef"
:defaultConfig="toolbarConfig" mode="default"/>
<Editor style="height: 500px; overflow-y: hidden;" v-model="valueHtml"
:defaultConfig="editorConfig" mode="default" @onCreated="handleCreated"/>
</div>
</template>
页面效果
代码Demo地址 https://gitee.com/Yang_Enzhe/Demos/tree/master/RichTextAndCodeHighlight