Vue3+TinyMCE6实战:手把手教你开发带目录导航的富文本编辑器(附完整代码)
Vue3TinyMCE6实战构建智能目录导航的富文本编辑器在当今内容驱动的应用开发中富文本编辑器已成为不可或缺的核心组件。而TinyMCE作为业界领先的WYSIWYG编辑器其6.x版本带来了更现代化的架构和更强大的扩展能力。本文将带您从零开始在Vue3环境中构建一个具备智能目录导航功能的企业级编辑器解决方案。1. 环境搭建与基础配置首先确保您的开发环境已准备好以下基础条件Node.js 16 和 npm/yarnVue3项目可通过vue create或Vite快速创建TinyMCE 6.x官方包社区版或商业版安装核心依赖npm install tinymce tinymce/tinymce-vue在public目录下创建tinymce文件夹放置以下资源public/ tinymce/ skins/ # 皮肤文件 icons/ # 图标集 plugins/ # 自定义插件目录 langs/ # 语言包如需中文基础配置示例src/utils/tinymce-config.jsexport const baseConfig { language: zh_CN, skin: oxide, content_css: default, menubar: file edit view insert format tools table help, toolbar: undo redo | styleselect | bold italic | alignleft aligncenter alignright | bullist numlist outdent indent | toc, plugins: lists link image table code help wordcount, height: 800, branding: false }提示TinyMCE6对插件系统进行了重构部分5.x插件需要适配新架构。遇到兼容性问题时可检查控制台错误并参考官方迁移指南。2. 目录导航插件开发2.1 插件架构设计目录导航插件的核心功能应包括实时解析文档中的标题结构h1-h6生成带锚点的可交互目录树支持平滑滚动定位提供目录更新机制创建插件文件public/tinymce/plugins/toc/plugin.js(function() { tinymce.PluginManager.add(toc, function(editor) { // 生成唯一ID的工具函数 const createIdGenerator (prefix) { let counter 0 return () { const guid Date.now().toString(32) return ${prefix}${guid}${(counter).toString(32)} } } // 核心功能实现... }) })()2.2 标题解析与目录生成实现标题解析的核心逻辑const parseHeaders () { const tocClass mce-toc const headers Array.from( editor.getBody().querySelectorAll(h1, h2, h3, h4, h5, h6) ).filter(el !el.classList.contains(tocClass)) return headers.map(header { if (!header.id) { header.id createIdGenerator(hdr_)() } return { id: header.id, level: parseInt(header.tagName.substring(1)), text: header.innerText, element: header } }) }目录生成算法采用多级嵌套列表结构const generateTocHTML (headers) { if (!headers.length) return let html div classmce-toc contenteditablefalse html h2 contenteditabletrue目录/h2ul let prevLevel headers[0].level headers.forEach((h, i) { const nextLevel headers[i1]?.level || null if (h.level prevLevel) { html ul } else if (h.level prevLevel) { html /li/ul.repeat(prevLevel - h.level) } else if (i 0) { html /li } html lia href#${h.id}${h.text}/a prevLevel h.level }) return html /ul/div }2.3 交互功能实现添加平滑滚动和点击事件处理const setupScrollBehavior () { editor.on(click, e { const toc editor.getBody().querySelector(.mce-toc) if (!toc || !toc.contains(e.target)) return if (e.target.tagName A) { e.preventDefault() const id e.target.getAttribute(href).substring(1) const target editor.getBody().querySelector(#${id}) target?.scrollIntoView({ behavior: smooth }) } }) }3. Vue3组件集成3.1 封装TinyMCE组件创建可复用的编辑器组件src/components/RichEditor.vuetemplate div classeditor-container Editor v-modelcontent :initeditorConfig :keyeditorKey / /div /template script setup import { ref, computed } from vue import Editor from tinymce/tinymce-vue const props defineProps({ modelValue: String, config: Object }) const emit defineEmits([update:modelValue]) const content computed({ get: () props.modelValue, set: (val) emit(update:modelValue, val) }) const editorKey ref(0) const editorConfig ref({ ...props.config, setup: (editor) { editor.on(init, () { console.log(Editor initialized) }) } }) /script3.2 实现双向数据绑定在父组件中使用template div classapp RichEditor v-modelcontent :configeditorConfig / /div /template script setup import { ref } from vue import RichEditor from ./components/RichEditor.vue import { baseConfig } from ./utils/tinymce-config const content ref(h1文档标题/h1p这里是正文内容.../p) const editorConfig ref({ ...baseConfig, plugins: [...baseConfig.plugins, toc], toolbar: ${baseConfig.toolbar} | tocupdate }) /script4. 高级功能扩展4.1 实时目录更新通过MutationObserver实现内容变化时的自动更新const setupAutoUpdate () { const observer new MutationObserver(mutations { if (mutations.some(m Array.from(m.addedNodes).some(n n.nodeType 1 /^H[1-6]$/i.test(n.tagName) ) )) { editor.execCommand(mceUpdateToc) } }) editor.on(init, () { observer.observe(editor.getBody(), { childList: true, subtree: true }) }) editor.on(remove, () observer.disconnect()) }4.2 样式定制与主题适配添加CSS样式确保目录与编辑器风格统一.mce-toc { border-left: 3px solid #eee; padding: 0.5rem 1rem; margin: 1rem 0; background: #f9f9f9; } .mce-toc h2 { font-size: 1.2em; margin-top: 0; } .mce-toc ul { list-style: none; padding-left: 1em; } .mce-toc li { margin: 0.3em 0; } .mce-toc a { color: #06c; text-decoration: none; } .mce-toc a:hover { text-decoration: underline; }4.3 性能优化策略对于大型文档的优化处理const throttledUpdate _.throttle(() { editor.execCommand(mceUpdateToc) }, 500, { leading: false }) editor.on(keyup, throttledUpdate) editor.on(change, throttledUpdate)5. 企业级解决方案实践在实际项目中我们还需要考虑以下增强功能多实例管理当页面中存在多个编辑器实例时确保插件状态隔离撤销/重做支持将目录操作纳入编辑器的撤销栈本地化扩展支持多语言目录标题可访问性为目录添加ARIA属性完整插件实现可封装为独立npm包便于团队共享{ name: tinymce-toc-plugin, version: 1.0.0, main: dist/plugin.js, files: [dist], peerDependencies: { tinymce: ^6.0.0 } }在多个Vue3项目中使用时可以通过动态导入实现按需加载const loadTocPlugin async () { await import(tinymce-toc-plugin) tinymce.init({ plugins: [toc], // 其他配置... }) }
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2417877.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!