Vue3——Tinymce6富文本编辑器的使用方法
vue
vuejs/vue: 是一个用于构建用户界面的 JavaScript 框架,具有简洁的语法和丰富的组件库,可以用于开发单页面应用程序和多页面应用程序。
项目地址:https://gitcode.com/gh_mirrors/vu/vue
免费下载资源
·
TinyMCE 6 是一款功能强大且灵活的富文本编辑器,可以嵌入到 Web 应用程序中。
一、安装
本文的讲解主要以tinymce6 版本为例
官网地址 Migrating from TinyMCE 5 to TinyMCE 6 | TinyMCE Documentation
要将 TinyMCE 添加到项目中,请执行以下操作:
-
使用 npm,在命令行上运行以下命令:
npm install tinymce
- 使用 Yarn,在命令行上运行以下命令:
yarn add t inymce@^6
二、初始化配置
import tinymce from "tinymce/tinymce";
import "tinymce/models/dom"; // 特别注意 tinymce 6.0.0 版本之后必须引入,否则不显示
import "tinymce/themes/silver/theme";
import Editor from "@tinymce/tinymce-vue"; // 引入组件
//引入工具栏图标和主题
import "tinymce/icons/default/icons";
import "tinymce/themes/silver";
// 引入富文本编辑器主题的js和css,不然显示出错
import "tinymce/themes/silver/theme.min";
import "tinymce/skins/ui/oxide/skin.min.css";
// 都是富文本插件
import "tinymce/icons/default";
import "tinymce/plugins/image";
// import "tinymce/plugins/link";
import "tinymce/plugins/code";
import "tinymce/plugins/table";
import "tinymce/plugins/lists";
import "tinymce/plugins/wordcount";
import "tinymce/plugins/autosave"; //自动保存
import "tinymce/plugins/save"; //保存
// import "tinymce/plugins/preview"; //预览
// 以上所有的样式在 node_modules 下面 tinymce 里面的 plugins 都能找到。
const init = {
//初始化数据
resize: false, //是否可自主拉伸
promotion: false, //Upgrade是否开启
statusbar: false, //状态栏是否显示
content_style: "body{margin:0;outline:none;font-family:'宋体';};",
language_url: "/langs/zh-Hans.js", // 引入语言包(该语言包在public下,注意文件名称)
language: "zh-Hans", // 这里名称根据 zh-Hans.js 里面写的名称而定
skin_url: "/skins/ui/oxide", // 这里引入的样式
plugins: "lists image code table wordcount autosave save", // 富文本插件
toolbar:
"| undo redo | fontfamily fontsize | italic bold underline strikethrough forecolor | alignleft alignright aligncenter alignjustify indent outdent lineheight numlist save",
branding: false, //是否禁用“Powered by TinyMCE”
menubar: false, //顶部菜单栏显示
font_size_formats: "11pt 12pt 14pt 16pt 18pt 24pt 36pt",
font_family_formats:
"微软雅黑='微软雅黑';宋体='宋体';黑体='黑体';仿宋='仿宋';楷体='楷体';隶书='隶书';幼圆='幼圆';Andale Mono=andale mono,times;Arial=arial,helvetica,sans-serif;Arial Black=arial black,avant garde;Book Antiqua=book antiqua,palatino;Comic Sans MS=comic sans ms,sans-serif;Courier New=courier new,courier;Georgia=georgia,palatino;Helvetica=helvetica;Impact=impact,chicago;Symbol=symbol;",
// paste_convert_word_fake_lists: false, // 插入word文档需要该属性
content_css: "/skins/content/default/content.css", //以css文件方式自定义可编辑区域的css样式,css文件需自己创建并引入
images_upload_handler: (blobInfo, success, failure) => {
// console.log(blobInfo.blob());
// 上传图片需要,FormData 格式的文件;
const formDataUp = new FormData();
// img 是接口需要的上传的属性名,一般属性名是 file
formDataUp.append("img", blobInfo.blob());
// // console.log(formDataUp);
axios.post("xxxx", formDataUp).then((res) => {
success("返回的上传图片后的地址");
});
},
inline: true,
// 将工具栏固定在顶部且blur时工具栏不会隐藏
fixed_toolbar_container: "#myToolbar",
// 此选项允许提供将在每次初始化编辑器实例时执行的函数。
init_instance_callback: function (editor) {
editor.fire("focus");
// 解决部署到生产环境时setContent 有可能会失效的问题
if (editor != null) {
getDetails();
}
},
setup: function (editor) {
// console.log(editor, "^^^^^^^^^");
editor.on("blur", function () {
return false;
});
// 禁止ctrl+c ctrl+v 复制
editor.on("keydown", function (e) {
if ((e.ctrlKey || e.metaKey) && e.key === "c") {
console.log(canCopy.value, "是否支付");
if (!canCopy.value) {
e.preventDefault();
}
}
});
// 监听编辑器撤销事件
editor.on("undo", function () {
console.log("当前正在执行撤销操作");
// 判断内容区是否为空
if (editor.getContent() === "") {
// 内容区为空,重新获取数据
console.log("内容区为空");
getDetails();
} else {
// 内容区不为空
console.log("内容区不为空");
}
});
// 编辑器内容发生变化时
editor.on("change", function () {
console.log("内容区发生变化");
let obj = {};
obj.hcn = document.getElementById("tinymce").innerHTML;
obj.di = di.value;
obj.index = -1;
if (!notUpdateHtml.value) {
updateHtmlContent({ ...obj }).then((res) => {
nextTick(() => {
MathJax.typesetPromise();
});
});
}
});
},
// 允许在 UI 中指定缩进/缩进按钮的缩进级别。
indentation: "2rem",
// 如果编辑器在缩进内容时应使用边距而不是填充,则设置此选项。
indent_use_margin: false,
// 自动保存时间间隔
autosave_interval: "5s",
// 自动草稿的有效期
autosave_retention: "20m",
// 当编辑器初始化时内容区为空时,Tinymce是否应自动还原存储在本地存储中的草稿
autosave_restore_when_empty: false,
// 当内容无变化时禁用保存按钮
save_enablewhendirty: false,
save_onsavecallback: function () {
ElMessage({
showClose: true,
message: "保存成功!",
type: "success",
});
},
// 粘贴过程中触发的事件
paste_preprocess: function (plugin, args) {
// 不可粘贴
// args.content = "";
},
};
onMounted(() => {
tinymce.init({}); // 初始化富文本
});
页面中使用
api-key 可以到官网去申请,以免可能会出现使用的过程中提示申请api-key的情况
<editor
style="margin-top: -25px"
id="tinymce"
api-key=""
:init="init"
></editor>
三、常见踩坑点
1.改变工具栏和编辑区默认上下的模式,将工具栏固定在某个容器中
inline: true,
// 将工具栏固定在顶部且blur时工具栏不会隐藏
fixed_toolbar_container: "#myToolbar",
2.如何将数组渲染至内容区中——使用tinymce中的setContent
使用凭借html的形式,然后使用tinymce中的setContent方法将数据渲染至内容区中
3.如何禁止复制内容区中的内容
setup: function (editor) {
// console.log(editor, "^^^^^^^^^");
editor.on("blur", function () {
return false;
});
// 禁止ctrl+c ctrl+v 复制
editor.on("keydown", function (e) {
if ((e.ctrlKey || e.metaKey) && (e.key === "c" || e.key === "v")) {
e.preventDefault(); // 阻止 Ctrl+C 和 Ctrl+V 的默认行为
}
});
},
若需要实现右击菜单栏的形式实现监听复制事件,可以通过监听编辑器的 复制 事件
editor.on("copy", function (e) {
if (!canCopy.value) {
e.preventDefault();
}
});
4.删除TinyMCE-6编辑器周围的蓝线-内联模式
<style>
* [contentEditable="true"]:focus
{ outline: 0px ; }
</style>
5.防止撤回到最初,内容区的内容消失
多次撤回后内容区的内容会为空,此时可以通过监听编辑器内容是否在执行撤销操作,如果进行撤销,通过tinymce中getContent的内容是否为空,为空则重新执行你获取数据的方法即可
(至于为何撤回时导致内容区的内容丢失,暂时还未找到原因,如有知晓如何解决,欢迎在评论区留言!)
6.实现设置字体选项默认为宋体
7.解决setContent有可能会失效的问题
// 此选项允许提供将在每次初始化编辑器实例时执行的函数。
init_instance_callback: function (editor) {
editor.fire("focus");
// 解决部署到生产环境时setContent 有可能会失效的问题
if (editor != null) {
getDetails();
}
},
8.tinymcea6 以上版本去除换行增加的p标签
9.如果当前有未保存的更改,关闭提示窗口
10.关于插入表格,给页面增添了多余的p标签,且原本的p标签丢失id
1.直接插入表格——table作为独立的块元素,原本的p标签挪到了table的后面,且table前面新增了一个p标签,并缺少了之前的id
2.enter插入表格——table作为独立的块元素,原本的p标签丢失了id
解决:通过监听内容区的点击事件,记录当前光标所在的 dom 节点 id(curHtmlId),如果table之前的p没有id,就为其添加curHtmlId,随后把没有innerText的p节点移除,以免造成页面重复id
editor.on("click", function (e) {
// 获取当前鼠标光标所在的 DOM 元素 id
const currentNode = editor.selection.getNode();
curHtmlId.value = currentNode.id;
console.log(curHtmlId.value, "############");
});
// 编辑器内容发生变化时
editor.on("change", function () {
setTimeout(() => {
console.log("内容区发生变化");
document.querySelectorAll("#tinymce p").forEach((p) => {
if (isIdeo.value == 0) {
p.style.backgroundColor = "white";
}
});
//处理表格
// 1.enter插入表格后,table作为独立的块元素,原本的p标签丢失了id
// 2.直接插入表格——table作为独立的块元素,原本的p标签挪到了table的后面,且table前面新增了一个p标签,并缺少了之前的id
const tables = document.querySelectorAll("table");
tables.forEach((table) => {
// 获取 table 前一个 p 标签
const prevP = table.previousElementSibling;
// 获取 table 后一个 p 标签
const nextP = table.nextElementSibling;
// 检查前后兄弟元素是否为 p 标签
if (
prevP &&
prevP.tagName.toLowerCase() === "p" &&
nextP &&
nextP.tagName.toLowerCase() === "p"
) {
if (!prevP.id) {
prevP.id = curHtmlId.value;
}
}
});
const ps = document.querySelectorAll("p");
ps.forEach((item) => {
if (item.tagName.toLowerCase() === "p") {
if (!item.innerText) {
item.remove();
}
}
});
let obj = {};
obj.hcn = document.getElementById("tinymce").innerHTML;
obj.di = di.value;
obj.index = "-1";
if (!notUpdateHtml.value) {
updateHtmlContent({ ...obj }).then((res) => {
// if (res.code == "00000") {
// hasHtml.value = true;
// tinymceEditorRef.value = tinymce.EditorManager.get("tinymce");
// tinymceEditorRef.value.setContent(res.obj);
// }
});
}
}, 300);
});
11. 如何插入数学公式
kityformula-editor 数学公式 | TinyMCE中文文档中文手册
插入公示后,如何实现点击公式可再次进入编辑状态
解决方法——找到插件的plugin.js文件,注释掉图中的代码即可
GitHub 加速计划 / vu / vue
207.52 K
33.66 K
下载
vuejs/vue: 是一个用于构建用户界面的 JavaScript 框架,具有简洁的语法和丰富的组件库,可以用于开发单页面应用程序和多页面应用程序。
最近提交(Master分支:1 个月前 )
73486cb5
* chore: fix link broken
Signed-off-by: snoppy <michaleli@foxmail.com>
* Update packages/template-compiler/README.md [skip ci]
---------
Signed-off-by: snoppy <michaleli@foxmail.com>
Co-authored-by: Eduardo San Martin Morote <posva@users.noreply.github.com> 3 个月前
e428d891
Updated Browser Compatibility reference. The previous currently returns HTTP 404. 3 个月前
更多推荐
已为社区贡献8条内容
所有评论(0)