vue2使用wangeditor實(shí)現(xiàn)數(shù)學(xué)公式和富文本編輯器
需求:
做一個(gè)帶有數(shù)學(xué)公式的富文本編輯器,在網(wǎng)上看了很多,這個(gè)最合適,借鑒了wangEditor富文本編輯器
這里面寫的是v3的整合富文本編輯器,我照著上面改成了v2的,本文章主要是實(shí)現(xiàn)步驟和錯(cuò)誤解決,源碼我放在最后了~
1.效果

2. 需要插件
npm install @wangeditor/editor @wangeditor/editor-for-vue @wangeditor/plugin-formula -S
jquery看自己項(xiàng)目里有沒(méi)有,沒(méi)有就下一個(gè)
npm install jquery

3.實(shí)現(xiàn)
wangEditor官網(wǎng):用于 Vue React | wangEditor
下載完插件后在所需頁(yè)面添加如下代碼即可實(shí)現(xiàn)(不包含數(shù)學(xué)公式)
<template>
<div>
<div>
<button @click="printEditorHtml">print html</button>
<button @click="getEditorText">print text</button>
</div>
<div style="border: 1px solid #ccc; margin-top: 10px">
<!-- 工具欄 -->
<Toolbar
style="border-bottom: 1px solid #ccc"
:editor="editor"
:defaultConfig="toolbarConfig"
/>
<!-- 編輯器 -->
<Editor
style="height: 400px; overflow-y: hidden"
:defaultConfig="editorConfig"
v-model="html"
@onChange="onChange"
@onCreated="onCreated"
/>
</div>
<div style="margin-top: 10px">
<textarea
v-model="html"
readonly
style="width: 100%; height: 200px; outline: none"
></textarea>
</div>
</div>
</template>
<script>
import { Editor, Toolbar } from "@wangeditor/editor-for-vue";
export default {
name: "MyEditor",
components: { Editor, Toolbar },
data() {
return {
editor: null,
html: "<p>hello world</p>",
toolbarConfig: {
// toolbarKeys: [ /* 顯示哪些菜單,如何排序、分組 */ ],
// excludeKeys: [ /* 隱藏哪些菜單 */ ],
},
editorConfig: {
placeholder: "請(qǐng)輸入內(nèi)容...",
// autoFocus: false,
// 所有的菜單配置,都要在 MENU_CONF 屬性下
MENU_CONF: {},
},
};
},
methods: {
onCreated(editor) {
this.editor = Object.seal(editor); // 【注意】一定要用 Object.seal() 否則會(huì)報(bào)錯(cuò)
},
onChange(editor) {
console.log("onChange", editor.getHtml()); // onChange 時(shí)獲取編輯器最新內(nèi)容
},
getEditorText() {
const editor = this.editor;
if (editor == null) return;
console.log(editor.getText()); // 執(zhí)行 editor API
},
printEditorHtml() {
const editor = this.editor;
if (editor == null) return;
console.log(editor.getHtml()); // 執(zhí)行 editor API
},
},
mounted() {
// 模擬 ajax 請(qǐng)求,異步渲染編輯器
setTimeout(() => {
this.html = "<p>Ajax 異步設(shè)置內(nèi)容 HTML</p>";
}, 1500);
},
beforeDestroy() {
const editor = this.editor;
if (editor == null) return;
editor.destroy(); // 組件銷毀時(shí),及時(shí)銷毀 editor ,重要?。?!
},
};
</script>
<style src="@wangeditor/editor/dist/css/style.css"></style>
3.1加入數(shù)學(xué)公式
在components文件下添加kityformula.js,內(nèi)容如下:
注意?。D標(biāo)地址別寫錯(cuò)了,不然圖標(biāo)顯示不出來(lái)
constructor里面就是一些基本的配置
import $ from "jquery";
import { formulaIcon } from "../assets/icons/svg-icon.ts";
class MyKityFormulaMenu {
constructor() {
this.title = "編輯公式";
this.iconSvg = formulaIcon;
this.tag = "button";
this.showModal = true;
this.modalWidth = 900;
this.modalHeight = 400;
}
// 菜單是否需要激活(如選中加粗文本,“加粗”菜單會(huì)激活),用不到則返回 false
isActive(editor) {
return false;
}
// 獲取菜單執(zhí)行時(shí)的 value ,用不到則返回空 字符串或 false
getValue(editor) {
return "";
}
// 菜單是否需要禁用(如選中 H1 ,“引用”菜單被禁用),用不到則返回 false
isDisabled(editor) {
return false;
}
// 點(diǎn)擊菜單時(shí)觸發(fā)的函數(shù)
exec(editor, value) {
// Modal menu ,這個(gè)函數(shù)不用寫,空著即可
}
// 彈出框 modal 的定位:1. 返回某一個(gè) SlateNode; 2. 返回 null (根據(jù)當(dāng)前選區(qū)自動(dòng)定位)
getModalPositionNode(editor) {
return null; // modal 依據(jù)選區(qū)定位
}
// 定義 modal 內(nèi)部的 DOM Element
getModalContentElem(editor) {
// panel 中需要用到的id
const inputIFrameId = "kityformula_" + Math.ceil(Math.random() * 10);
const btnOkId = "kityformula-btn" + Math.ceil(Math.random() * 10);
const $content = $(`
<div>
<iframe id="${inputIFrameId}" class="iframe" height="400px" width="100%" frameborder="0" scrolling="no" src="/kityformula/index.html"></iframe>
</div>`);
const $button = $(
`<button id="${btnOkId}" class="right" style='margin: 5px 0'>
確認(rèn)插入
</button>`
);
$content.append($button);
$button.on("click", () => {
// 執(zhí)行插入公式
const node = document.getElementById(inputIFrameId);
const kfe = node.contentWindow.kfe;
kfe.execCommand("get.image.data", function (data) {
// 獲取base64
// console.log(data.img);
});
let latex = kfe.execCommand("get.source");
latex = latex.replace(/\s/g, ""); // 去掉空格
const formulaNode = {
type: "paragraph",
children: [
{
type: "formula",
value: latex,
children: [
{
text: "",
},
],
},
],
};
console.log(editor, '編輯器');
editor.insertNode(formulaNode);
editor.hidePanelOrModal();
});
return $content[0]; // 返回 DOM Element 類型
// PS:也可以把 $content 緩存下來(lái),這樣不用每次重復(fù)創(chuàng)建、重復(fù)綁定事件,優(yōu)化性能
}
}
const menuConf = {
key: "kityFormula", // menu key ,唯一。注冊(cè)之后,需通過(guò) toolbarKeys 配置到工具欄
factory() {
return new MyKityFormulaMenu();
},
};
export default menuConf;代碼講解:content就是數(shù)學(xué)公式彈窗,點(diǎn)擊確認(rèn)插入之后會(huì)添加節(jié)點(diǎn)在編輯器內(nèi)
const $content = $(`
<div>
<iframe id="${inputIFrameId}" class="iframe" height="400px" width="100%" frameborder="0" scrolling="no" src="/kityformula/index.html"></iframe>
</div>`);
const $button = $(
`<button id="${btnOkId}" class="right" style='margin: 5px 0'>
確認(rèn)插入
</button>`
);
3.2在pulic文件下添加數(shù)學(xué)公式相關(guān)代碼

3.3主要頁(yè)面代碼講解
這個(gè)代碼意思就是插入注冊(cè),添加到編輯器當(dāng)中
import kityformula from "@/components/kityformula";
import { Boot } from "@wangeditor/editor";
toolbarConfig: {
// 插入編輯公式菜單
insertKeys: {
index: 0,
keys: [
"kityFormula", // “編輯公式”菜單
],
},
// excludeKeys: [ /* 隱藏哪些菜單 */ ],
},
created() {
Boot.registerMenu(kityformula);
},3.4解決編輯完成數(shù)學(xué)公式后內(nèi)容沒(méi)插入編輯器bug
意思就是寫完了數(shù)學(xué)公式后沒(méi)反應(yīng),內(nèi)容沒(méi)添加進(jìn)編輯器當(dāng)中
解決如下:
import formulaModule from "@wangeditor/plugin-formula";
import { Boot } from "@wangeditor/editor";
created() {
Boot.registerModule(formulaModule);
},
此時(shí)再次運(yùn)行會(huì)報(bào)錯(cuò):
Module not found: Error: Can't resolve 'katex' in xxx
解決:
下載這個(gè),默認(rèn)下載最新版5.1.0,下載完成后就不會(huì)報(bào)錯(cuò)
npm install myscript-math-web
3.5完整頁(yè)面代碼
<template>
<div class="content-box">
<div class="container" style="width: 1000px; margin: 0 auto">
<div>
<button @click="printEditorHtml">獲取編輯器html</button>
<button @click="getEditorText">獲取編輯器文本</button>
</div>
<div style="border: 1px solid #ccc; margin-top: 10px; text-align: left">
<!-- 工具欄 -->
<Toolbar
style="border-bottom: 1px solid #ccc"
:editor="editor"
:defaultConfig="toolbarConfig"
/>
<!-- 編輯器 -->
<Editor
style="height: 500px; overflow-y: hidden"
:defaultConfig="editorConfig"
v-model="html"
@onChange="onChange"
@onCreated="onCreated"
@onFocus="handleFocus"
/>
</div>
<div style="margin-top: 10px">
<textarea
v-model="html"
readonly
style="width: 100%; height: 200px; outline: none"
></textarea>
</div>
</div>
</div>
</template>
<script>
import { Editor, Toolbar } from "@wangeditor/editor-for-vue";
import kityformula from "@/components/kityformula";
import { Boot } from "@wangeditor/editor";
import formulaModule from "@wangeditor/plugin-formula";
export default {
name: "MyEditor",
components: { Editor, Toolbar },
data() {
return {
editor: null,
html: "<p>hello world</p>",
toolbarConfig: {
// 插入編輯公式菜單
insertKeys: {
index: 0,
keys: [
"kityFormula", // “編輯公式”菜單
],
},
// excludeKeys: [ /* 隱藏哪些菜單 */ ],
},
editorConfig: {
placeholder: "請(qǐng)輸入內(nèi)容...",
// autoFocus: false,
// 所有的菜單配置,都要在 MENU_CONF 屬性下
MENU_CONF: {},
},
};
},
methods: {
onCreated(editor) {
console.log("created", editor);
this.editor = Object.seal(editor); // 【注意】一定要用 Object.seal() 否則會(huì)報(bào)錯(cuò)
},
onChange(editor) {
console.log("onChange", editor.getHtml()); // onChange 時(shí)獲取編輯器最新內(nèi)容
},
handleFocus(editor) {
console.log("focus", editor);
},
getEditorText() {
const editor = this.editor;
if (editor == null) return;
console.log(editor.getText()); // 執(zhí)行 editor API
},
printEditorHtml() {
const editor = this.editor;
if (editor == null) return;
console.log(editor.getHtml()); // 執(zhí)行 editor API
},
},
created() {
Boot.registerMenu(kityformula);
Boot.registerModule(formulaModule);
},
mounted() {
// 模擬 ajax 請(qǐng)求,異步渲染編輯器
setTimeout(() => {
this.html = "<p>Ajax 異步設(shè)置內(nèi)容 HTML</p>";
}, 1500);
},
beforeDestroy() {
const editor = this.editor;
if (editor == null) return;
editor.destroy(); // 組件銷毀時(shí),及時(shí)銷毀 editor ,重要?。。?
},
};
</script>
<style src="@wangeditor/editor/dist/css/style.css"></style>以上就是vue2使用wangeditor實(shí)現(xiàn)數(shù)學(xué)公式和富文本編輯器的詳細(xì)內(nèi)容,更多關(guān)于vue2 wangeditor的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Vue2 SSR渲染根據(jù)不同頁(yè)面修改 meta
本篇文章主要介紹了Vue2 SSR渲染根據(jù)不同頁(yè)面修改 meta,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-11-11
spring-cloud-stream的手動(dòng)消息確認(rèn)問(wèn)題
這篇文章主要介紹了spring-cloud-stream的手動(dòng)消息確認(rèn)問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-05-05
vue 實(shí)現(xiàn)dot-dropdown的實(shí)例代碼
這篇文章主要介紹了vue實(shí)現(xiàn)dot-dropdown的相關(guān)操作,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2025-06-06
vue2使用ts?vue-class-component的過(guò)程
vue-property-decorator?是一個(gè)?Vue.js?的裝飾器庫(kù),它提供了一些裝飾器來(lái)讓你在?Vue?組件中定義屬性、計(jì)算屬性、方法、事件等,本文給大家介紹vue2使用ts?vue-class-component的相關(guān)知識(shí),感興趣的朋友一起看看吧2023-11-11
Vue組件中常見(jiàn)的props默認(rèn)值陷阱問(wèn)題
這篇文章主要介紹了避免Vue組件中常見(jiàn)的props默認(rèn)值陷阱,本文通過(guò)問(wèn)題展示及解決方案給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-09-09
詳解vue-cli與webpack結(jié)合如何處理靜態(tài)資源
本篇文章主要介紹了詳解vue-cli與webpack結(jié)合如何處理靜態(tài)資源,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-09-09
Vue.js表單標(biāo)簽中的單選按鈕、復(fù)選按鈕和下拉列表的取值問(wèn)題
這篇文章主要介紹了Vue.js表單標(biāo)簽中的單選按鈕、復(fù)選按鈕和下拉列表的取值問(wèn)題,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2017-11-11

