Vue3下tinymce-vue ^4.0.4对接laravel-filemanager点击确认报错如何解决
问题排查与解决方案
核心问题原因
- 响应式变量作用域错误:你将
tinymceref声明在onMounted回调内部,外部的file_picker_callback函数无法访问该变量,调用tinymce.activeEditor时会触发未定义报错。 - TinyMCE实例获取方式错误:
@tinymce/tinymce-vue4.x适配Vue3的版本,需要通过ref的getEditor()方法获取编辑器实例,不能直接调用全局tinymce.activeEditor。 - 缺少文件选择结果监听:laravel-filemanager选中文件后会通过
postMessage传递文件地址,你没有监听该事件,无法将选中的文件路径回传给TinyMCE的文件选择回调。
修复后的完整代码
<template> <div> <editor ref="tinymceRef" name="tinymce" class="form-control my-editor" api-key="api-key" v-model="body" :init="{ path_absolute : '/', selector: 'textarea.my-editor', relative_urls: false, plugins: [ 'advlist autolink lists link image charmap print preview hr anchor pagebreak', 'searchreplace wordcount visualblocks visualchars code fullscreen', 'insertdatetime media nonbreaking save table directionality', 'emoticons template paste textpattern' ], toolbar: 'insertfile undo redo | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image media', file_picker_callback : filePickerCallback }" /> </div> </template> <script> import { onMounted, ref, onUnmounted } from 'vue'; import Editor from '@tinymce/tinymce-vue'; export default { name: 'EventsForm', components: { Editor }, setup(props, context) { const tinymceRef = ref(null); const body = ref(''); // 存储TinyMCE的文件选择回调 let currentFileCallback = null; // 监听laravel-filemanager返回的文件选择结果 const handleMessage = (e) => { if (e.origin !== window.location.origin) return; if (e.data && e.data.field_name && currentFileCallback) { currentFileCallback(e.data.url); currentFileCallback = null; } } onMounted(() => { window.addEventListener('message', handleMessage); }) onUnmounted(() => { window.removeEventListener('message', handleMessage); }) const filePickerCallback = (callback, value, meta) => { currentFileCallback = callback; const x = window.innerWidth || document.documentElement.clientWidth || document.getElementsByTagName('body')[0].clientWidth; const y = window.innerHeight || document.documentElement.clientHeight || document.getElementsByTagName('body')[0].clientHeight; let cmsURL = window.location.origin + '/laravel-filemanager?field_name=' + meta.fieldname; cmsURL = meta.filetype == 'image' ? cmsURL + "&type=Images" : cmsURL + "&type=Files"; // 通过ref获取编辑器实例调用弹窗 const editor = tinymceRef.value.getEditor(); editor.windowManager.openUrl({ url: cmsURL, title: 'Filemanager', width: x * 0.8, height: y * 0.8, resizable: "yes", close_previous: "no" }); } return { tinymceRef, body, filePickerCallback } } } </script>
关键修改说明
- 将
tinymceref移到setup顶层声明,重命名为tinymceRef避免和全局TinyMCE变量混淆,补充了双向绑定需要的body响应式变量。 - 新增
currentFileCallback变量存储TinyMCE传入的文件选择回调,监听message事件接收laravel-filemanager返回的文件地址后触发回调回传路径。 - 调用
tinymceRef.value.getEditor()获取编辑器实例,替代原来的全局tinymce.activeEditor调用。 - 组件卸载时移除
message事件监听,避免内存泄漏。
内容的提问来源于stack exchange,提问作者Jérémie Chazelle
相关产品推荐
相关产品推荐

