如何在Nuxt3(Vue3)中通过PluginManager添加可交互自定义TinyMCE插件
解决方案:Nuxt3中TinyMCE插件集成与应用交互
一、修复当前LaTeX插件不显示的问题
你的代码存在两个核心问题导致插件无法显示:
- plugins数组未包含latex:toolbar里声明了
latex按钮,但plugins列表中未添加该插件,TinyMCE无法识别并加载。 - setup函数写法错误:setup函数的参数是editor实例,直接操作
window.tinymce在Nuxt3的SSR环境下可能存在时机问题,且注册插件的方式不符合规范。
修改后的代码示例:
<template> <tinymce-editor api-key="someKey" v-model="tinycontent" :init="tinyconfig" /> </template> <script> import Editor from "@tinymce/tinymce-vue"; // 导入你的LaTeX插件(支持ES模块或动态导入IIFE格式) import latexPlugin from "./path/to/latex.min.js"; export default { components: { "tinymce-editor": Editor, }, data() { return { tinycontent: '', tinyconfig: { toolbar: "bold italic underline code | latex", // 必须将latex加入plugins数组 plugins: "lists link image table code help wordcount latex", content_css: "https://cdn.jsdelivr.net/npm/katex@0.16.6/dist/katex.min.css", // 正确使用setup函数:接收editor参数,在初始化阶段注册插件 setup: (editor) => { // 注册LaTeX插件 tinymce.PluginManager.add("latex", latexPlugin); }, }, }; }, // 确保组件仅在客户端渲染,避免SSR环境下的window问题 clientOnly: true, }; </script>
如果你的latex.min.js是IIFE自执行格式,改用动态导入确保客户端执行:
setup: async (editor) => { const { default: latex } = await import("./path/to/latex.min.js"); tinymce.PluginManager.add("latex", latex); }
二、构建无需public文件夹的术语表插件(实现应用交互)
要实现从应用内列表插入词汇的功能,可按以下步骤构建独立插件:
1. 编写术语表插件(ES模块形式)
创建TermGlossaryPlugin.js,直接作为模块导出,无需放置在public文件夹:
export default function(editor) { // 从编辑器配置中获取应用传递的术语列表 const glossaryTerms = editor.settings.glossaryTerms || []; // 添加工具栏按钮 editor.ui.registry.addButton('glossary', { icon: 'list', tooltip: '插入术语', onAction: () => { // 打开弹窗供用户选择术语 editor.windowManager.open({ title: '选择术语', body: { type: 'listbox', name: 'term', label: '术语', values: glossaryTerms.map(term => ({ text: term.label, value: term.value })) }, onSubmit: (api) => { const selectedTerm = api.getData().term; // 将选中的术语插入编辑器内容 editor.insertContent(`<span class="glossary-term">${selectedTerm}</span>`); api.close(); } }); } }); }
2. 在Nuxt3组件中集成插件并传递应用数据
在编辑器配置中导入插件,同时传递应用内的术语列表:
<template> <tinymce-editor api-key="someKey" v-model="tinycontent" :init="tinyconfig" /> </template> <script> import Editor from "@tinymce/tinymce-vue"; import TermGlossaryPlugin from "./path/to/TermGlossaryPlugin.js"; import latexPlugin from "./path/to/latex.min.js"; export default { components: { "tinymce-editor": Editor, }, data() { return { tinycontent: '', // 应用内的术语列表(可从接口获取或本地定义) glossaryList: [ { label: "Nuxt3", value: "Nuxt3" }, { label: "TinyMCE", value: "TinyMCE" }, { label: "LaTeX", value: "LaTeX" } ], tinyconfig: { toolbar: "bold italic underline code | latex glossary", plugins: "lists link image table code help wordcount latex", // 将术语列表传递给插件 glossaryTerms: this.glossaryList, setup: (editor) => { // 注册术语表插件 tinymce.PluginManager.add("glossary", TermGlossaryPlugin); // 注册LaTeX插件 tinymce.PluginManager.add("latex", latexPlugin); }, }, }; }, clientOnly: true, }; </script>
3. 实现插件与应用的双向交互
如果需要插件触发应用内的方法(比如更新术语列表),可在editor实例上挂载回调函数:
// 在setup函数中挂载应用方法到editor setup: (editor) => { editor.updateGlossary = () => { // 调用应用内的方法更新术语列表 this.fetchGlossaryList(); }; // 注册插件... } // 在插件中调用该方法触发应用更新 editor.updateGlossary();
关键注意事项
- SSR兼容:TinyMCE是客户端库,需确保插件注册逻辑仅在客户端执行,可使用
clientOnly组件或process.client判断:if (process.client) { tinymce.PluginManager.add("glossary", TermGlossaryPlugin); } - 插件注册时机:必须在TinyMCE初始化完成前注册插件,setup函数是最佳执行时机。
- 数据传递:通过
editor.settings传递应用数据到插件,无需依赖全局变量。
内容的提问来源于stack exchange,提问作者luxor37
相关产品推荐
相关产品推荐

